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