1 //===- MCSubtargetInfo.cpp - Subtarget Information ------------------------===// 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 #include "llvm/MC/MCSubtargetInfo.h" 11 #include "llvm/ADT/ArrayRef.h" 12 #include "llvm/ADT/StringRef.h" 13 #include "llvm/MC/MCInstrItineraries.h" 14 #include "llvm/MC/MCSchedule.h" 15 #include "llvm/MC/SubtargetFeature.h" 16 #include "llvm/Support/raw_ostream.h" 17 #include <algorithm> 18 #include <cassert> 19 #include <cstring> 20 21 using namespace llvm; 22 23 static FeatureBitset getFeatures(StringRef CPU, StringRef FS, 24 ArrayRef<SubtargetFeatureKV> ProcDesc, 25 ArrayRef<SubtargetFeatureKV> ProcFeatures) { 26 SubtargetFeatures Features(FS); 27 return Features.getFeatureBits(CPU, ProcDesc, ProcFeatures); 28 } 29 30 void MCSubtargetInfo::InitMCProcessorInfo(StringRef CPU, StringRef FS) { 31 FeatureBits = getFeatures(CPU, FS, ProcDesc, ProcFeatures); 32 if (!CPU.empty()) 33 CPUSchedModel = &getSchedModelForCPU(CPU); 34 else 35 CPUSchedModel = &MCSchedModel::GetDefaultSchedModel(); 36 } 37 38 void MCSubtargetInfo::setDefaultFeatures(StringRef CPU, StringRef FS) { 39 FeatureBits = getFeatures(CPU, FS, ProcDesc, ProcFeatures); 40 } 41 42 MCSubtargetInfo::MCSubtargetInfo( 43 const Triple &TT, StringRef C, StringRef FS, 44 ArrayRef<SubtargetFeatureKV> PF, ArrayRef<SubtargetFeatureKV> PD, 45 const SubtargetInfoKV *ProcSched, const MCWriteProcResEntry *WPR, 46 const MCWriteLatencyEntry *WL, const MCReadAdvanceEntry *RA, 47 const InstrStage *IS, const unsigned *OC, const unsigned *FP) 48 : TargetTriple(TT), CPU(C), ProcFeatures(PF), ProcDesc(PD), 49 ProcSchedModels(ProcSched), WriteProcResTable(WPR), WriteLatencyTable(WL), 50 ReadAdvanceTable(RA), Stages(IS), OperandCycles(OC), ForwardingPaths(FP) { 51 InitMCProcessorInfo(CPU, FS); 52 } 53 54 /// ToggleFeature - Toggle a feature and returns the re-computed feature 55 /// bits. This version does not change the implied bits. 56 FeatureBitset MCSubtargetInfo::ToggleFeature(uint64_t FB) { 57 FeatureBits.flip(FB); 58 return FeatureBits; 59 } 60 61 FeatureBitset MCSubtargetInfo::ToggleFeature(const FeatureBitset &FB) { 62 FeatureBits ^= FB; 63 return FeatureBits; 64 } 65 66 /// ToggleFeature - Toggle a feature and returns the re-computed feature 67 /// bits. This version will also change all implied bits. 68 FeatureBitset MCSubtargetInfo::ToggleFeature(StringRef FS) { 69 SubtargetFeatures::ToggleFeature(FeatureBits, FS, ProcFeatures); 70 return FeatureBits; 71 } 72 73 FeatureBitset MCSubtargetInfo::ApplyFeatureFlag(StringRef FS) { 74 SubtargetFeatures::ApplyFeatureFlag(FeatureBits, FS, ProcFeatures); 75 return FeatureBits; 76 } 77 78 bool MCSubtargetInfo::checkFeatures(StringRef FS) const { 79 SubtargetFeatures T(FS); 80 FeatureBitset Set, All; 81 for (std::string F : T.getFeatures()) { 82 SubtargetFeatures::ApplyFeatureFlag(Set, F, ProcFeatures); 83 if (F[0] == '-') 84 F[0] = '+'; 85 SubtargetFeatures::ApplyFeatureFlag(All, F, ProcFeatures); 86 } 87 return (FeatureBits & All) == Set; 88 } 89 90 const MCSchedModel &MCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const { 91 assert(ProcSchedModels && "Processor machine model not available!"); 92 93 ArrayRef<SubtargetInfoKV> SchedModels(ProcSchedModels, ProcDesc.size()); 94 95 assert(std::is_sorted(SchedModels.begin(), SchedModels.end(), 96 [](const SubtargetInfoKV &LHS, const SubtargetInfoKV &RHS) { 97 return strcmp(LHS.Key, RHS.Key) < 0; 98 }) && 99 "Processor machine model table is not sorted"); 100 101 // Find entry 102 auto Found = 103 std::lower_bound(SchedModels.begin(), SchedModels.end(), CPU); 104 if (Found == SchedModels.end() || StringRef(Found->Key) != CPU) { 105 if (CPU != "help") // Don't error if the user asked for help. 106 errs() << "'" << CPU 107 << "' is not a recognized processor for this target" 108 << " (ignoring processor)\n"; 109 return MCSchedModel::GetDefaultSchedModel(); 110 } 111 assert(Found->Value && "Missing processor SchedModel value"); 112 return *(const MCSchedModel *)Found->Value; 113 } 114 115 InstrItineraryData 116 MCSubtargetInfo::getInstrItineraryForCPU(StringRef CPU) const { 117 const MCSchedModel &SchedModel = getSchedModelForCPU(CPU); 118 return InstrItineraryData(SchedModel, Stages, OperandCycles, ForwardingPaths); 119 } 120 121 /// Initialize an InstrItineraryData instance. 122 void MCSubtargetInfo::initInstrItins(InstrItineraryData &InstrItins) const { 123 InstrItins = InstrItineraryData(getSchedModel(), Stages, OperandCycles, 124 ForwardingPaths); 125 } 126