• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   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   virtual ~MCSubtargetInfo() = default;
67 
getTargetTriple()68   const Triple &getTargetTriple() const { return TargetTriple; }
getCPU()69   StringRef getCPU() const { return CPU; }
70 
getFeatureBits()71   const FeatureBitset& getFeatureBits() const { return FeatureBits; }
setFeatureBits(const FeatureBitset & FeatureBits_)72   void setFeatureBits(const FeatureBitset &FeatureBits_) {
73     FeatureBits = FeatureBits_;
74   }
75 
hasFeature(unsigned Feature)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.
getSchedModel()116   const MCSchedModel &getSchedModel() const { return *CPUSchedModel; }
117 
118   /// Return an iterator at the first process resource consumed by the given
119   /// scheduling class.
getWriteProcResBegin(const MCSchedClassDesc * SC)120   const MCWriteProcResEntry *getWriteProcResBegin(
121     const MCSchedClassDesc *SC) const {
122     return &WriteProcResTable[SC->WriteProcResIdx];
123   }
getWriteProcResEnd(const MCSchedClassDesc * SC)124   const MCWriteProcResEntry *getWriteProcResEnd(
125     const MCSchedClassDesc *SC) const {
126     return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries;
127   }
128 
getWriteLatencyEntry(const MCSchedClassDesc * SC,unsigned DefIdx)129   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     return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx];
135   }
136 
getReadAdvanceCycles(const MCSchedClassDesc * SC,unsigned UseIdx,unsigned WriteResID)137   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     for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx],
143            *E = I + SC->NumReadAdvanceEntries; I != E; ++I) {
144       if (I->UseIdx < UseIdx)
145         continue;
146       if (I->UseIdx > UseIdx)
147         break;
148       // Find the first WriteResIdx match, which has the highest cycle count.
149       if (!I->WriteResourceID || I->WriteResourceID == WriteResID) {
150         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
resolveVariantSchedClass(unsigned SchedClass,const MCInst * MI,unsigned CPUID)164   resolveVariantSchedClass(unsigned SchedClass, const MCInst *MI,
165                            unsigned CPUID) const {
166     return 0;
167   }
168 
169   /// Check whether the CPU string is valid.
isCPUStringValid(StringRef CPU)170   bool isCPUStringValid(StringRef CPU) const {
171     auto Found = std::lower_bound(ProcDesc.begin(), ProcDesc.end(), CPU);
172     return Found != ProcDesc.end() && StringRef(Found->Key) == CPU;
173   }
174 
175   /// Returns string representation of scheduler comment
getSchedInfoStr(MCInst const & MCI)176   virtual std::string getSchedInfoStr(MCInst const &MCI) const {
177     return {};
178   }
179 };
180 
181 } // end namespace llvm
182 
183 #endif // LLVM_MC_MCSUBTARGETINFO_H
184