blob: c7472a28c7747329f758af1a96a24d29bf27959c [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- llvm/MC/MCSubtargetInfo.h - Subtarget Information --------*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
7//===----------------------------------------------------------------------===//
8//
9// This file describes the subtarget options of a Target machine.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_MC_MCSUBTARGETINFO_H
14#define LLVM_MC_MCSUBTARGETINFO_H
15
16#include "llvm/ADT/ArrayRef.h"
17#include "llvm/ADT/StringRef.h"
18#include "llvm/ADT/Triple.h"
19#include "llvm/MC/MCInstrItineraries.h"
20#include "llvm/MC/MCSchedule.h"
21#include "llvm/MC/SubtargetFeature.h"
22#include <algorithm>
23#include <cassert>
24#include <cstdint>
25#include <string>
26
27namespace llvm {
28
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010029class MCInst;
30
31//===----------------------------------------------------------------------===//
32///
33/// Generic base class for all target subtargets.
34///
35class MCSubtargetInfo {
36 Triple TargetTriple;
37 std::string CPU; // CPU being targeted.
38 ArrayRef<SubtargetFeatureKV> ProcFeatures; // Processor feature list
39 ArrayRef<SubtargetFeatureKV> ProcDesc; // Processor descriptions
40
41 // Scheduler machine model
42 const SubtargetInfoKV *ProcSchedModels;
43 const MCWriteProcResEntry *WriteProcResTable;
44 const MCWriteLatencyEntry *WriteLatencyTable;
45 const MCReadAdvanceEntry *ReadAdvanceTable;
46 const MCSchedModel *CPUSchedModel;
47
48 const InstrStage *Stages; // Instruction itinerary stages
49 const unsigned *OperandCycles; // Itinerary operand cycles
50 const unsigned *ForwardingPaths;
51 FeatureBitset FeatureBits; // Feature bits for current CPU + FS
52
53public:
54 MCSubtargetInfo(const MCSubtargetInfo &) = default;
55 MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS,
56 ArrayRef<SubtargetFeatureKV> PF,
57 ArrayRef<SubtargetFeatureKV> PD,
58 const SubtargetInfoKV *ProcSched,
59 const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL,
60 const MCReadAdvanceEntry *RA, const InstrStage *IS,
61 const unsigned *OC, const unsigned *FP);
62 MCSubtargetInfo() = delete;
63 MCSubtargetInfo &operator=(const MCSubtargetInfo &) = delete;
64 MCSubtargetInfo &operator=(MCSubtargetInfo &&) = delete;
65 virtual ~MCSubtargetInfo() = default;
66
67 const Triple &getTargetTriple() const { return TargetTriple; }
68 StringRef getCPU() const { return CPU; }
69
70 const FeatureBitset& getFeatureBits() const { return FeatureBits; }
71 void setFeatureBits(const FeatureBitset &FeatureBits_) {
72 FeatureBits = FeatureBits_;
73 }
74
75 bool hasFeature(unsigned Feature) const {
76 return FeatureBits[Feature];
77 }
78
79protected:
80 /// Initialize the scheduling model and feature bits.
81 ///
82 /// FIXME: Find a way to stick this in the constructor, since it should only
83 /// be called during initialization.
84 void InitMCProcessorInfo(StringRef CPU, StringRef FS);
85
86public:
87 /// Set the features to the default for the given CPU with an appended feature
88 /// string.
89 void setDefaultFeatures(StringRef CPU, StringRef FS);
90
91 /// Toggle a feature and return the re-computed feature bits.
92 /// This version does not change the implied bits.
93 FeatureBitset ToggleFeature(uint64_t FB);
94
95 /// Toggle a feature and return the re-computed feature bits.
96 /// This version does not change the implied bits.
97 FeatureBitset ToggleFeature(const FeatureBitset& FB);
98
99 /// Toggle a set of features and return the re-computed feature bits.
100 /// This version will also change all implied bits.
101 FeatureBitset ToggleFeature(StringRef FS);
102
103 /// Apply a feature flag and return the re-computed feature bits, including
104 /// all feature bits implied by the flag.
105 FeatureBitset ApplyFeatureFlag(StringRef FS);
106
107 /// Check whether the subtarget features are enabled/disabled as per
108 /// the provided string, ignoring all other features.
109 bool checkFeatures(StringRef FS) const;
110
111 /// Get the machine model of a CPU.
112 const MCSchedModel &getSchedModelForCPU(StringRef CPU) const;
113
114 /// Get the machine model for this subtarget's CPU.
115 const MCSchedModel &getSchedModel() const { return *CPUSchedModel; }
116
117 /// Return an iterator at the first process resource consumed by the given
118 /// scheduling class.
119 const MCWriteProcResEntry *getWriteProcResBegin(
120 const MCSchedClassDesc *SC) const {
121 return &WriteProcResTable[SC->WriteProcResIdx];
122 }
123 const MCWriteProcResEntry *getWriteProcResEnd(
124 const MCSchedClassDesc *SC) const {
125 return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries;
126 }
127
128 const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC,
129 unsigned DefIdx) const {
130 assert(DefIdx < SC->NumWriteLatencyEntries &&
131 "MachineModel does not specify a WriteResource for DefIdx");
132
133 return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx];
134 }
135
136 int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx,
137 unsigned WriteResID) const {
138 // TODO: The number of read advance entries in a class can be significant
139 // (~50). Consider compressing the WriteID into a dense ID of those that are
140 // used by ReadAdvance and representing them as a bitset.
141 for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx],
142 *E = I + SC->NumReadAdvanceEntries; I != E; ++I) {
143 if (I->UseIdx < UseIdx)
144 continue;
145 if (I->UseIdx > UseIdx)
146 break;
147 // Find the first WriteResIdx match, which has the highest cycle count.
148 if (!I->WriteResourceID || I->WriteResourceID == WriteResID) {
149 return I->Cycles;
150 }
151 }
152 return 0;
153 }
154
Andrew Walbran16937d02019-10-22 13:54:20 +0100155 /// Return the set of ReadAdvance entries declared by the scheduling class
156 /// descriptor in input.
157 ArrayRef<MCReadAdvanceEntry>
158 getReadAdvanceEntries(const MCSchedClassDesc &SC) const {
159 if (!SC.NumReadAdvanceEntries)
160 return ArrayRef<MCReadAdvanceEntry>();
161 return ArrayRef<MCReadAdvanceEntry>(&ReadAdvanceTable[SC.ReadAdvanceIdx],
162 SC.NumReadAdvanceEntries);
163 }
164
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100165 /// Get scheduling itinerary of a CPU.
166 InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;
167
168 /// Initialize an InstrItineraryData instance.
169 void initInstrItins(InstrItineraryData &InstrItins) const;
170
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100171 /// Resolve a variant scheduling class for the given MCInst and CPU.
172 virtual unsigned
173 resolveVariantSchedClass(unsigned SchedClass, const MCInst *MI,
174 unsigned CPUID) const {
175 return 0;
176 }
177
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100178 /// Check whether the CPU string is valid.
179 bool isCPUStringValid(StringRef CPU) const {
180 auto Found = std::lower_bound(ProcDesc.begin(), ProcDesc.end(), CPU);
181 return Found != ProcDesc.end() && StringRef(Found->Key) == CPU;
182 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100183};
184
185} // end namespace llvm
186
187#endif // LLVM_MC_MCSUBTARGETINFO_H