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