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/MC/MCInstrItineraries.h" 18 #include "llvm/MC/SubtargetFeature.h" 19 #include <string> 20 21 namespace llvm { 22 23 class StringRef; 24 25 //===----------------------------------------------------------------------===// 26 /// 27 /// MCSubtargetInfo - Generic base class for all target subtargets. 28 /// 29 class MCSubtargetInfo { 30 std::string TargetTriple; // Target triple 31 std::string CPU; // CPU being targeted. 32 ArrayRef<SubtargetFeatureKV> ProcFeatures; // Processor feature list 33 ArrayRef<SubtargetFeatureKV> ProcDesc; // Processor descriptions 34 35 // Scheduler machine model 36 const SubtargetInfoKV *ProcSchedModels; 37 const MCWriteProcResEntry *WriteProcResTable; 38 const MCWriteLatencyEntry *WriteLatencyTable; 39 const MCReadAdvanceEntry *ReadAdvanceTable; 40 MCSchedModel CPUSchedModel; 41 42 const InstrStage *Stages; // Instruction itinerary stages 43 const unsigned *OperandCycles; // Itinerary operand cycles 44 const unsigned *ForwardingPaths; // Forwarding paths 45 uint64_t FeatureBits; // Feature bits for current CPU + FS 46 47 public: 48 void InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS, 49 ArrayRef<SubtargetFeatureKV> PF, 50 ArrayRef<SubtargetFeatureKV> PD, 51 const SubtargetInfoKV *ProcSched, 52 const MCWriteProcResEntry *WPR, 53 const MCWriteLatencyEntry *WL, 54 const MCReadAdvanceEntry *RA, 55 const InstrStage *IS, 56 const unsigned *OC, const unsigned *FP); 57 58 /// getTargetTriple - Return the target triple string. getTargetTriple()59 StringRef getTargetTriple() const { 60 return TargetTriple; 61 } 62 63 /// getCPU - Return the CPU string. getCPU()64 StringRef getCPU() const { 65 return CPU; 66 } 67 68 /// getFeatureBits - Return the feature bits. 69 /// getFeatureBits()70 uint64_t getFeatureBits() const { 71 return FeatureBits; 72 } 73 74 /// setFeatureBits - Set the feature bits. 75 /// setFeatureBits(uint64_t FeatureBits_)76 void setFeatureBits(uint64_t FeatureBits_) { FeatureBits = FeatureBits_; } 77 78 /// InitMCProcessorInfo - Set or change the CPU (optionally supplemented with 79 /// feature string). Recompute feature bits and scheduling model. 80 void InitMCProcessorInfo(StringRef CPU, StringRef FS); 81 82 /// InitCPUSchedModel - Recompute scheduling model based on CPU. 83 void InitCPUSchedModel(StringRef CPU); 84 85 /// ToggleFeature - Toggle a feature and returns the re-computed feature 86 /// bits. This version does not change the implied bits. 87 uint64_t ToggleFeature(uint64_t FB); 88 89 /// ToggleFeature - Toggle a feature and returns the re-computed feature 90 /// bits. This version will also change all implied bits. 91 uint64_t ToggleFeature(StringRef FS); 92 93 /// getSchedModelForCPU - Get the machine model of a CPU. 94 /// 95 MCSchedModel getSchedModelForCPU(StringRef CPU) const; 96 97 /// getSchedModel - Get the machine model for this subtarget's CPU. 98 /// getSchedModel()99 const MCSchedModel &getSchedModel() const { return CPUSchedModel; } 100 101 /// Return an iterator at the first process resource consumed by the given 102 /// scheduling class. getWriteProcResBegin(const MCSchedClassDesc * SC)103 const MCWriteProcResEntry *getWriteProcResBegin( 104 const MCSchedClassDesc *SC) const { 105 return &WriteProcResTable[SC->WriteProcResIdx]; 106 } getWriteProcResEnd(const MCSchedClassDesc * SC)107 const MCWriteProcResEntry *getWriteProcResEnd( 108 const MCSchedClassDesc *SC) const { 109 return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries; 110 } 111 getWriteLatencyEntry(const MCSchedClassDesc * SC,unsigned DefIdx)112 const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC, 113 unsigned DefIdx) const { 114 assert(DefIdx < SC->NumWriteLatencyEntries && 115 "MachineModel does not specify a WriteResource for DefIdx"); 116 117 return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx]; 118 } 119 getReadAdvanceCycles(const MCSchedClassDesc * SC,unsigned UseIdx,unsigned WriteResID)120 int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx, 121 unsigned WriteResID) const { 122 // TODO: The number of read advance entries in a class can be significant 123 // (~50). Consider compressing the WriteID into a dense ID of those that are 124 // used by ReadAdvance and representing them as a bitset. 125 for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx], 126 *E = I + SC->NumReadAdvanceEntries; I != E; ++I) { 127 if (I->UseIdx < UseIdx) 128 continue; 129 if (I->UseIdx > UseIdx) 130 break; 131 // Find the first WriteResIdx match, which has the highest cycle count. 132 if (!I->WriteResourceID || I->WriteResourceID == WriteResID) { 133 return I->Cycles; 134 } 135 } 136 return 0; 137 } 138 139 /// getInstrItineraryForCPU - Get scheduling itinerary of a CPU. 140 /// 141 InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const; 142 143 /// Initialize an InstrItineraryData instance. 144 void initInstrItins(InstrItineraryData &InstrItins) const; 145 146 /// Check whether the CPU string is valid. isCPUStringValid(StringRef CPU)147 bool isCPUStringValid(StringRef CPU) { 148 auto Found = std::find_if(ProcDesc.begin(), ProcDesc.end(), 149 [=](const SubtargetFeatureKV &KV) { 150 return CPU == KV.Key; 151 }); 152 return Found != ProcDesc.end(); 153 } 154 }; 155 156 } // End llvm namespace 157 158 #endif 159