Skip to content

Commit 8e00afc

Browse files
authored
[LLVM][TableGen] Change SubtargetEmitter to use const RecordKeeper (#108763)
Change SubtargetEmitter to use const RecordKeeper. This is a part of effort to have better const correctness in TableGen backends: https://discourse.llvm.org/t/psa-planned-changes-to-tablegen-getallderiveddefinitions-api-potential-downstream-breakages/81089
1 parent 87e8b53 commit 8e00afc

File tree

2 files changed

+46
-59
lines changed

2 files changed

+46
-59
lines changed

llvm/utils/TableGen/Common/CodeGenSchedule.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ class CodeGenSchedModels {
489489
return ModelDef;
490490
}
491491

492-
const CodeGenProcModel &getModelForProc(Record *ProcDef) const {
492+
const CodeGenProcModel &getModelForProc(const Record *ProcDef) const {
493493
const Record *ModelDef = getModelOrItinDef(ProcDef);
494494
ProcModelMapTy::const_iterator I = ProcModelMap.find(ModelDef);
495495
assert(I != ProcModelMap.end() && "missing machine model");

llvm/utils/TableGen/SubtargetEmitter.cpp

Lines changed: 45 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ using namespace llvm;
4343

4444
namespace {
4545

46+
using FeatureMapTy = DenseMap<const Record *, unsigned>;
47+
4648
/// Sorting predicate to sort record pointers by their
4749
/// FieldName field.
4850
struct LessRecordFieldFieldName {
@@ -81,22 +83,22 @@ class SubtargetEmitter {
8183
};
8284

8385
CodeGenTarget TGT;
84-
RecordKeeper &Records;
86+
const RecordKeeper &Records;
8587
CodeGenSchedModels &SchedModels;
8688
std::string Target;
8789

88-
void Enumeration(raw_ostream &OS, DenseMap<Record *, unsigned> &FeatureMap);
90+
FeatureMapTy Enumeration(raw_ostream &OS);
8991
void EmitSubtargetInfoMacroCalls(raw_ostream &OS);
90-
unsigned FeatureKeyValues(raw_ostream &OS,
91-
const DenseMap<Record *, unsigned> &FeatureMap);
92-
unsigned CPUKeyValues(raw_ostream &OS,
93-
const DenseMap<Record *, unsigned> &FeatureMap);
94-
void FormItineraryStageString(const std::string &Names, Record *ItinData,
95-
std::string &ItinString, unsigned &NStages);
96-
void FormItineraryOperandCycleString(Record *ItinData,
92+
unsigned FeatureKeyValues(raw_ostream &OS, const FeatureMapTy &FeatureMap);
93+
unsigned CPUKeyValues(raw_ostream &OS, const FeatureMapTy &FeatureMap);
94+
void FormItineraryStageString(const std::string &Names,
95+
const Record *ItinData, std::string &ItinString,
96+
unsigned &NStages);
97+
void FormItineraryOperandCycleString(const Record *ItinData,
9798
std::string &ItinString,
9899
unsigned &NOperandCycles);
99-
void FormItineraryBypassString(const std::string &Names, Record *ItinData,
100+
void FormItineraryBypassString(const std::string &Names,
101+
const Record *ItinData,
100102
std::string &ItinString,
101103
unsigned NOperandCycles);
102104
void EmitStageAndOperandCycleData(
@@ -139,7 +141,7 @@ class SubtargetEmitter {
139141
void ParseFeaturesFunction(raw_ostream &OS);
140142

141143
public:
142-
SubtargetEmitter(RecordKeeper &R)
144+
SubtargetEmitter(const RecordKeeper &R)
143145
: TGT(R), Records(R), SchedModels(TGT.getSchedModels()),
144146
Target(TGT.getName()) {}
145147

@@ -151,16 +153,13 @@ class SubtargetEmitter {
151153
//
152154
// Enumeration - Emit the specified class as an enumeration.
153155
//
154-
void SubtargetEmitter::Enumeration(raw_ostream &OS,
155-
DenseMap<Record *, unsigned> &FeatureMap) {
156-
// Get all records of class and sort
157-
std::vector<Record *> DefList =
156+
FeatureMapTy SubtargetEmitter::Enumeration(raw_ostream &OS) {
157+
ArrayRef<const Record *> DefList =
158158
Records.getAllDerivedDefinitions("SubtargetFeature");
159-
llvm::sort(DefList, LessRecord());
160159

161160
unsigned N = DefList.size();
162161
if (N == 0)
163-
return;
162+
return FeatureMapTy();
164163
if (N + 1 > MAX_SUBTARGET_FEATURES)
165164
PrintFatalError(
166165
"Too many subtarget features! Bump MAX_SUBTARGET_FEATURES.");
@@ -170,10 +169,11 @@ void SubtargetEmitter::Enumeration(raw_ostream &OS,
170169
// Open enumeration.
171170
OS << "enum {\n";
172171

172+
FeatureMapTy FeatureMap;
173173
// For each record
174174
for (unsigned i = 0; i < N; ++i) {
175175
// Next record
176-
Record *Def = DefList[i];
176+
const Record *Def = DefList[i];
177177

178178
// Get and emit name
179179
OS << " " << Def->getName() << " = " << i << ",\n";
@@ -188,10 +188,12 @@ void SubtargetEmitter::Enumeration(raw_ostream &OS,
188188
// Close enumeration and namespace
189189
OS << "};\n";
190190
OS << "} // end namespace " << Target << "\n";
191+
return FeatureMap;
191192
}
192193

193-
static void printFeatureMask(raw_ostream &OS, RecVec &FeatureList,
194-
const DenseMap<Record *, unsigned> &FeatureMap) {
194+
static void printFeatureMask(raw_ostream &OS,
195+
ArrayRef<const Record *> FeatureList,
196+
const FeatureMapTy &FeatureMap) {
195197
std::array<uint64_t, MAX_SUBTARGET_WORDS> Mask = {};
196198
for (const Record *Feature : FeatureList) {
197199
unsigned Bit = FeatureMap.lookup(Feature);
@@ -212,7 +214,7 @@ static void printFeatureMask(raw_ostream &OS, RecVec &FeatureList,
212214
void SubtargetEmitter::EmitSubtargetInfoMacroCalls(raw_ostream &OS) {
213215
OS << "\n#ifdef GET_SUBTARGETINFO_MACRO\n";
214216

215-
std::vector<Record *> FeatureList =
217+
std::vector<const Record *> FeatureList =
216218
Records.getAllDerivedDefinitions("SubtargetFeature");
217219
llvm::sort(FeatureList, LessRecordFieldFieldName());
218220

@@ -250,11 +252,10 @@ void SubtargetEmitter::EmitSubtargetInfoMacroCalls(raw_ostream &OS) {
250252
// FeatureKeyValues - Emit data of all the subtarget features. Used by the
251253
// command line.
252254
//
253-
unsigned SubtargetEmitter::FeatureKeyValues(
254-
raw_ostream &OS, const DenseMap<Record *, unsigned> &FeatureMap) {
255-
const RecordKeeper &RCConst = Records;
255+
unsigned SubtargetEmitter::FeatureKeyValues(raw_ostream &OS,
256+
const FeatureMapTy &FeatureMap) {
256257
std::vector<const Record *> FeatureList =
257-
RCConst.getAllDerivedDefinitions("SubtargetFeature");
258+
Records.getAllDerivedDefinitions("SubtargetFeature");
258259

259260
// Remove features with empty name.
260261
llvm::erase_if(FeatureList, [](const Record *Rec) {
@@ -300,11 +301,10 @@ unsigned SubtargetEmitter::FeatureKeyValues(
300301
// CPUKeyValues - Emit data of all the subtarget processors. Used by command
301302
// line.
302303
//
303-
unsigned
304-
SubtargetEmitter::CPUKeyValues(raw_ostream &OS,
305-
const DenseMap<Record *, unsigned> &FeatureMap) {
304+
unsigned SubtargetEmitter::CPUKeyValues(raw_ostream &OS,
305+
const FeatureMapTy &FeatureMap) {
306306
// Gather and sort processor information
307-
std::vector<Record *> ProcessorList =
307+
std::vector<const Record *> ProcessorList =
308308
Records.getAllDerivedDefinitions("Processor");
309309
llvm::sort(ProcessorList, LessRecordFieldName());
310310

@@ -318,7 +318,7 @@ SubtargetEmitter::CPUKeyValues(raw_ostream &OS,
318318
<< "extern const llvm::SubtargetSubTypeKV " << Target
319319
<< "SubTypeKV[] = {\n";
320320

321-
for (Record *Processor : ProcessorList) {
321+
for (const Record *Processor : ProcessorList) {
322322
StringRef Name = Processor->getValueAsString("Name");
323323
RecVec FeatureList = Processor->getValueAsListOfDefs("Features");
324324
RecVec TuneFeatureList = Processor->getValueAsListOfDefs("TuneFeatures");
@@ -349,11 +349,11 @@ SubtargetEmitter::CPUKeyValues(raw_ostream &OS,
349349
// of stages.
350350
//
351351
void SubtargetEmitter::FormItineraryStageString(const std::string &Name,
352-
Record *ItinData,
352+
const Record *ItinData,
353353
std::string &ItinString,
354354
unsigned &NStages) {
355355
// Get states list
356-
RecVec StageList = ItinData->getValueAsListOfDefs("Stages");
356+
ConstRecVec StageList = ItinData->getValueAsListOfConstDefs("Stages");
357357

358358
// For each stage
359359
unsigned N = NStages = StageList.size();
@@ -395,7 +395,7 @@ void SubtargetEmitter::FormItineraryStageString(const std::string &Name,
395395
// number of operands that has cycles specified.
396396
//
397397
void SubtargetEmitter::FormItineraryOperandCycleString(
398-
Record *ItinData, std::string &ItinString, unsigned &NOperandCycles) {
398+
const Record *ItinData, std::string &ItinString, unsigned &NOperandCycles) {
399399
// Get operand cycle list
400400
std::vector<int64_t> OperandCycleList =
401401
ItinData->getValueAsListOfInts("OperandCycles");
@@ -411,10 +411,10 @@ void SubtargetEmitter::FormItineraryOperandCycleString(
411411
}
412412

413413
void SubtargetEmitter::FormItineraryBypassString(const std::string &Name,
414-
Record *ItinData,
414+
const Record *ItinData,
415415
std::string &ItinString,
416416
unsigned NOperandCycles) {
417-
RecVec BypassList = ItinData->getValueAsListOfDefs("Bypasses");
417+
ConstRecVec BypassList = ItinData->getValueAsListOfConstDefs("Bypasses");
418418
unsigned N = BypassList.size();
419419
unsigned i = 0;
420420
ListSeparator LS;
@@ -511,7 +511,7 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(
511511
SchedClassIdx < SchedClassEnd; ++SchedClassIdx) {
512512

513513
// Next itinerary data
514-
Record *ItinData = ProcModel.ItinDefList[SchedClassIdx];
514+
const Record *ItinData = ProcModel.ItinDefList[SchedClassIdx];
515515

516516
// Get string and stage count
517517
std::string ItinStageString;
@@ -746,7 +746,7 @@ SubtargetEmitter::EmitRegisterFileTables(const CodeGenProcModel &ProcModel,
746746
// Add entries to the cost table.
747747
for (const CodeGenRegisterCost &RC : RF.Costs) {
748748
OS << " { ";
749-
Record *Rec = RC.RCDef;
749+
const Record *Rec = RC.RCDef;
750750
if (Rec->getValue("Namespace"))
751751
OS << Rec->getValueAsString("Namespace") << "::";
752752
OS << Rec->getName() << "RegClassID, " << RC.Cost << ", "
@@ -843,7 +843,7 @@ void SubtargetEmitter::EmitProcessorResources(const CodeGenProcModel &ProcModel,
843843
int BufferSize = PRDef->getValueAsInt("BufferSize");
844844
if (PRDef->isSubClassOf("ProcResGroup")) {
845845
RecVec ResUnits = PRDef->getValueAsListOfDefs("Resources");
846-
for (Record *RU : ResUnits) {
846+
for (const Record *RU : ResUnits) {
847847
NumUnits += RU->getValueAsInt("NumUnits");
848848
SubUnitsOffset += RU->getValueAsInt("NumUnits");
849849
}
@@ -1279,7 +1279,7 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
12791279
if (ValidWrites.empty())
12801280
WriteIDs.push_back(0);
12811281
else {
1282-
for (Record *VW : ValidWrites) {
1282+
for (const Record *VW : ValidWrites) {
12831283
unsigned WriteID = SchedModels.getSchedRWIdx(VW, /*IsRead=*/false);
12841284
assert(WriteID != 0 &&
12851285
"Expected a valid SchedRW in the list of ValidWrites");
@@ -1548,16 +1548,12 @@ void SubtargetEmitter::EmitSchedModel(raw_ostream &OS) {
15481548
EmitProcessorModels(OS);
15491549
}
15501550

1551-
static void emitPredicateProlog(RecordKeeper &Records, raw_ostream &OS) {
1551+
static void emitPredicateProlog(const RecordKeeper &Records, raw_ostream &OS) {
15521552
std::string Buffer;
15531553
raw_string_ostream Stream(Buffer);
15541554

1555-
// Collect all the PredicateProlog records and print them to the output
1556-
// stream.
1557-
std::vector<Record *> Prologs =
1558-
Records.getAllDerivedDefinitions("PredicateProlog");
1559-
llvm::sort(Prologs, LessRecord());
1560-
for (Record *P : Prologs)
1555+
// Print all PredicateProlog records to the output stream.
1556+
for (const Record *P : Records.getAllDerivedDefinitions("PredicateProlog"))
15611557
Stream << P->getValueAsString("Code") << '\n';
15621558

15631559
OS << Buffer;
@@ -1878,9 +1874,8 @@ void SubtargetEmitter::emitGetMacroFusions(const std::string &ClassName,
18781874
// Produces a subtarget specific function for parsing
18791875
// the subtarget features string.
18801876
void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS) {
1881-
std::vector<Record *> Features =
1877+
ArrayRef<const Record *> Features =
18821878
Records.getAllDerivedDefinitions("SubtargetFeature");
1883-
llvm::sort(Features, LessRecord());
18841879

18851880
OS << "// ParseSubtargetFeatures - Parses features string setting specified\n"
18861881
<< "// subtarget options.\n"
@@ -1904,7 +1899,7 @@ void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS) {
19041899
OS << " InitMCProcessorInfo(CPU, TuneCPU, FS);\n"
19051900
<< " const FeatureBitset &Bits = getFeatureBits();\n";
19061901

1907-
for (Record *R : Features) {
1902+
for (const Record *R : Features) {
19081903
// Next record
19091904
StringRef Instance = R->getName();
19101905
StringRef Value = R->getValueAsString("Value");
@@ -1995,28 +1990,20 @@ void SubtargetEmitter::run(raw_ostream &OS) {
19951990
OS << "\n#ifdef GET_SUBTARGETINFO_ENUM\n";
19961991
OS << "#undef GET_SUBTARGETINFO_ENUM\n\n";
19971992

1998-
DenseMap<Record *, unsigned> FeatureMap;
1999-
20001993
OS << "namespace llvm {\n";
2001-
Enumeration(OS, FeatureMap);
1994+
auto FeatureMap = Enumeration(OS);
20021995
OS << "} // end namespace llvm\n\n";
20031996
OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n";
20041997

20051998
EmitSubtargetInfoMacroCalls(OS);
20061999

20072000
OS << "namespace llvm {\n";
2008-
#if 0
2009-
OS << "namespace {\n";
2010-
#endif
20112001
unsigned NumFeatures = FeatureKeyValues(OS, FeatureMap);
20122002
OS << "\n";
20132003
EmitSchedModel(OS);
20142004
OS << "\n";
20152005
unsigned NumProcs = CPUKeyValues(OS, FeatureMap);
20162006
OS << "\n";
2017-
#if 0
2018-
OS << "} // end anonymous namespace\n\n";
2019-
#endif
20202007

20212008
// MCInstrInfo initialization routine.
20222009
emitGenMCSubtargetInfo(OS);

0 commit comments

Comments
 (0)