Skip to content

Commit e5c418f

Browse files
authored
[NFC][TableGen] Adopt CodeGenHelpers in SubtargetEmitter (#163820)
- Adopt ifdef and namespace emitters in SubtargeEmitter. - To aid that, factor out emission of different sections of the code into individual helper functions.
1 parent a12600c commit e5c418f

File tree

2 files changed

+119
-90
lines changed

2 files changed

+119
-90
lines changed

llvm/include/llvm/TableGen/CodeGenHelpers.h

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,37 @@
2121

2222
namespace llvm {
2323

24-
// Simple RAII helper for emitting ifdef-undef-endif scope.
24+
// Simple RAII helper for emitting ifdef-undef-endif scope. `LateUndef` controls
25+
// whether the undef is emitted at the start of the scope (false) or at the end
26+
// of the scope (true).
2527
class IfDefEmitter {
2628
public:
27-
IfDefEmitter(raw_ostream &OS, StringRef Name) : Name(Name.str()), OS(OS) {
28-
OS << "#ifdef " << Name << "\n"
29-
<< "#undef " << Name << "\n\n";
29+
IfDefEmitter(raw_ostream &OS, StringRef Name, bool LateUndef = false)
30+
: Name(Name.str()), OS(OS), LateUndef(LateUndef) {
31+
OS << "#ifdef " << Name << "\n";
32+
if (!LateUndef)
33+
OS << "#undef " << Name << "\n";
34+
OS << "\n";
35+
}
36+
~IfDefEmitter() { close(); }
37+
38+
// Explicit function to close the ifdef scopes.
39+
void close() {
40+
if (Closed)
41+
return;
42+
43+
OS << "\n";
44+
if (LateUndef)
45+
OS << "#undef " << Name << "\n";
46+
OS << "#endif // " << Name << "\n\n";
47+
Closed = true;
3048
}
31-
~IfDefEmitter() { OS << "\n#endif // " << Name << "\n\n"; }
3249

3350
private:
3451
std::string Name;
3552
raw_ostream &OS;
53+
bool LateUndef;
54+
bool Closed = false;
3655
};
3756

3857
// Simple RAII helper for emitting header include guard (ifndef-define-endif).
@@ -43,11 +62,20 @@ class IncludeGuardEmitter {
4362
OS << "#ifndef " << Name << "\n"
4463
<< "#define " << Name << "\n\n";
4564
}
46-
~IncludeGuardEmitter() { OS << "\n#endif // " << Name << "\n"; }
65+
~IncludeGuardEmitter() { close(); }
66+
67+
// Explicit function to close the ifdef scopes.
68+
void close() {
69+
if (Closed)
70+
return;
71+
OS << "\n#endif // " << Name << "\n\n";
72+
Closed = true;
73+
}
4774

4875
private:
4976
std::string Name;
5077
raw_ostream &OS;
78+
bool Closed = false;
5179
};
5280

5381
// Simple RAII helper for emitting namespace scope. Name can be a single
@@ -65,7 +93,9 @@ class NamespaceEmitter {
6593

6694
// Explicit function to close the namespace scopes.
6795
void close() {
68-
if (!Closed && !Name.empty())
96+
if (Closed)
97+
return;
98+
if (!Name.empty())
6999
OS << "\n} // namespace " << Name << "\n";
70100
Closed = true;
71101
}

llvm/utils/TableGen/SubtargetEmitter.cpp

Lines changed: 82 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "llvm/Support/Debug.h"
2828
#include "llvm/Support/Format.h"
2929
#include "llvm/Support/raw_ostream.h"
30+
#include "llvm/TableGen/CodeGenHelpers.h"
3031
#include "llvm/TableGen/Error.h"
3132
#include "llvm/TableGen/Record.h"
3233
#include "llvm/TableGen/StringToOffsetTable.h"
@@ -75,7 +76,15 @@ class SubtargetEmitter : TargetFeaturesEmitter {
7576
CodeGenTarget TGT;
7677
CodeGenSchedModels &SchedModels;
7778

79+
FeatureMapTy emitEnums(raw_ostream &OS);
7880
void emitSubtargetInfoMacroCalls(raw_ostream &OS);
81+
std::tuple<unsigned, unsigned, unsigned>
82+
emitMCDesc(raw_ostream &OS, const FeatureMapTy &FeatureMap);
83+
void emitTargetDesc(raw_ostream &OS);
84+
void emitHeader(raw_ostream &OS);
85+
void emitCtor(raw_ostream &OS, unsigned NumNames, unsigned NumFeatures,
86+
unsigned NumProcs);
87+
7988
unsigned featureKeyValues(raw_ostream &OS, const FeatureMapTy &FeatureMap);
8089
unsigned cpuKeyValues(raw_ostream &OS, const FeatureMapTy &FeatureMap);
8190
unsigned cpuNames(raw_ostream &OS);
@@ -141,7 +150,9 @@ class SubtargetEmitter : TargetFeaturesEmitter {
141150
/// Emit some information about the SubtargetFeature as calls to a macro so
142151
/// that they can be used from C++.
143152
void SubtargetEmitter::emitSubtargetInfoMacroCalls(raw_ostream &OS) {
144-
OS << "\n#ifdef GET_SUBTARGETINFO_MACRO\n";
153+
// Undef the GET_SUBTARGETINFO_MACRO macro at the end of the scope since it's
154+
// used within the scope.
155+
IfDefEmitter IfDefMacro(OS, "GET_SUBTARGETINFO_MACRO", /*LateUndef=*/true);
145156

146157
std::vector<const Record *> FeatureList =
147158
Records.getAllDerivedDefinitions("SubtargetFeature");
@@ -167,14 +178,6 @@ void SubtargetEmitter::emitSubtargetInfoMacroCalls(raw_ostream &OS) {
167178
OS << "GET_SUBTARGETINFO_MACRO(" << FieldName << ", " << Default << ", "
168179
<< Getter << ")\n";
169180
}
170-
OS << "#undef GET_SUBTARGETINFO_MACRO\n";
171-
OS << "#endif // GET_SUBTARGETINFO_MACRO\n\n";
172-
173-
OS << "\n#ifdef GET_SUBTARGETINFO_MC_DESC\n";
174-
OS << "#undef GET_SUBTARGETINFO_MC_DESC\n\n";
175-
176-
if (Target == "AArch64")
177-
OS << "#include \"llvm/TargetParser/AArch64TargetParser.h\"\n\n";
178181
}
179182

180183
//
@@ -440,26 +443,24 @@ void SubtargetEmitter::emitStageAndOperandCycleData(
440443
continue;
441444

442445
StringRef Name = ProcModel.ItinsDef->getName();
443-
OS << "\n// Functional units for \"" << Name << "\"\n"
444-
<< "namespace " << Name << "FU {\n";
445-
446-
for (const auto &[Idx, FU] : enumerate(FUs))
447-
OS << " const InstrStage::FuncUnits " << FU->getName() << " = 1ULL << "
448-
<< Idx << ";\n";
446+
{
447+
OS << "\n// Functional units for \"" << Name << "\"\n";
448+
NamespaceEmitter FUNamespace(OS, (Name + Twine("FU")).str());
449449

450-
OS << "} // end namespace " << Name << "FU\n";
450+
for (const auto &[Idx, FU] : enumerate(FUs))
451+
OS << " const InstrStage::FuncUnits " << FU->getName() << " = 1ULL << "
452+
<< Idx << ";\n";
453+
}
451454

452455
ConstRecVec BPs = ProcModel.ItinsDef->getValueAsListOfDefs("BP");
453456
if (BPs.empty())
454457
continue;
455-
OS << "\n// Pipeline forwarding paths for itineraries \"" << Name << "\"\n"
456-
<< "namespace " << Name << "Bypass {\n";
458+
OS << "\n// Pipeline forwarding paths for itineraries \"" << Name << "\"\n";
459+
NamespaceEmitter BypassNamespace(OS, (Name + Twine("Bypass")).str());
457460

458461
OS << " const unsigned NoBypass = 0;\n";
459462
for (const auto &[Idx, BP] : enumerate(BPs))
460463
OS << " const unsigned " << BP->getName() << " = 1 << " << Idx << ";\n";
461-
462-
OS << "} // end namespace " << Name << "Bypass\n";
463464
}
464465

465466
// Begin stages table
@@ -1940,13 +1941,14 @@ void SubtargetEmitter::parseFeaturesFunction(raw_ostream &OS) {
19401941
}
19411942

19421943
void SubtargetEmitter::emitGenMCSubtargetInfo(raw_ostream &OS) {
1943-
OS << "namespace " << Target << "_MC {\n"
1944-
<< "unsigned resolveVariantSchedClassImpl(unsigned SchedClass,\n"
1945-
<< " const MCInst *MI, const MCInstrInfo *MCII, "
1946-
<< "const MCSubtargetInfo &STI, unsigned CPUID) {\n";
1947-
emitSchedModelHelpersImpl(OS, /* OnlyExpandMCPredicates */ true);
1948-
OS << "}\n";
1949-
OS << "} // end namespace " << Target << "_MC\n\n";
1944+
{
1945+
NamespaceEmitter NS(OS, (Target + Twine("_MC")).str());
1946+
OS << "unsigned resolveVariantSchedClassImpl(unsigned SchedClass,\n"
1947+
<< " const MCInst *MI, const MCInstrInfo *MCII, "
1948+
<< "const MCSubtargetInfo &STI, unsigned CPUID) {\n";
1949+
emitSchedModelHelpersImpl(OS, /* OnlyExpandMCPredicates */ true);
1950+
OS << "}\n";
1951+
}
19501952

19511953
OS << "struct " << Target
19521954
<< "GenMCSubtargetInfo : public MCSubtargetInfo {\n";
@@ -1982,46 +1984,37 @@ void SubtargetEmitter::emitGenMCSubtargetInfo(raw_ostream &OS) {
19821984
}
19831985

19841986
void SubtargetEmitter::emitMcInstrAnalysisPredicateFunctions(raw_ostream &OS) {
1985-
OS << "\n#ifdef GET_STIPREDICATE_DECLS_FOR_MC_ANALYSIS\n";
1986-
OS << "#undef GET_STIPREDICATE_DECLS_FOR_MC_ANALYSIS\n\n";
1987-
19881987
STIPredicateExpander PE(Target, /*Indent=*/0);
1989-
PE.setExpandForMC(true);
1990-
PE.setByRef(true);
1991-
for (const STIPredicateFunction &Fn : SchedModels.getSTIPredicates())
1992-
PE.expandSTIPredicate(OS, Fn);
1993-
1994-
OS << "#endif // GET_STIPREDICATE_DECLS_FOR_MC_ANALYSIS\n\n";
19951988

1996-
OS << "\n#ifdef GET_STIPREDICATE_DEFS_FOR_MC_ANALYSIS\n";
1997-
OS << "#undef GET_STIPREDICATE_DEFS_FOR_MC_ANALYSIS\n\n";
1989+
{
1990+
IfDefEmitter IfDefDecls(OS, "GET_STIPREDICATE_DECLS_FOR_MC_ANALYSIS");
1991+
PE.setExpandForMC(true);
1992+
PE.setByRef(true);
1993+
for (const STIPredicateFunction &Fn : SchedModels.getSTIPredicates())
1994+
PE.expandSTIPredicate(OS, Fn);
1995+
}
19981996

1997+
IfDefEmitter IfDefDefs(OS, "GET_STIPREDICATE_DEFS_FOR_MC_ANALYSIS");
19991998
std::string ClassPrefix = Target + "MCInstrAnalysis";
20001999
PE.setExpandDefinition(true);
20012000
PE.setClassPrefix(ClassPrefix);
20022001
for (const STIPredicateFunction &Fn : SchedModels.getSTIPredicates())
20032002
PE.expandSTIPredicate(OS, Fn);
2004-
2005-
OS << "#endif // GET_STIPREDICATE_DEFS_FOR_MC_ANALYSIS\n\n";
20062003
}
20072004

2008-
//
2009-
// SubtargetEmitter::run - Main subtarget enumeration emitter.
2010-
//
2011-
void SubtargetEmitter::run(raw_ostream &OS) {
2012-
emitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
2013-
2014-
OS << "\n#ifdef GET_SUBTARGETINFO_ENUM\n";
2015-
OS << "#undef GET_SUBTARGETINFO_ENUM\n\n";
2016-
2017-
OS << "namespace llvm {\n";
2018-
auto FeatureMap = enumeration(OS);
2019-
OS << "} // end namespace llvm\n\n";
2020-
OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n";
2005+
FeatureMapTy SubtargetEmitter::emitEnums(raw_ostream &OS) {
2006+
IfDefEmitter IfDef(OS, "GET_SUBTARGETINFO_ENUM");
2007+
NamespaceEmitter NS(OS, "llvm");
2008+
return enumeration(OS);
2009+
}
20212010

2022-
emitSubtargetInfoMacroCalls(OS);
2011+
std::tuple<unsigned, unsigned, unsigned>
2012+
SubtargetEmitter::emitMCDesc(raw_ostream &OS, const FeatureMapTy &FeatureMap) {
2013+
IfDefEmitter IfDef(OS, "GET_SUBTARGETINFO_MC_DESC");
2014+
if (Target == "AArch64")
2015+
OS << "#include \"llvm/TargetParser/AArch64TargetParser.h\"\n\n";
2016+
NamespaceEmitter LlvmNS(OS, "llvm");
20232017

2024-
OS << "namespace llvm {\n";
20252018
unsigned NumFeatures = featureKeyValues(OS, FeatureMap);
20262019
OS << "\n";
20272020
emitSchedModel(OS);
@@ -2067,35 +2060,33 @@ void SubtargetEmitter::run(raw_ostream &OS) {
20672060
OS << "nullptr, nullptr, nullptr";
20682061
}
20692062
OS << ");\n}\n\n";
2063+
return {NumNames, NumFeatures, NumProcs};
2064+
}
20702065

2071-
OS << "} // end namespace llvm\n\n";
2072-
2073-
OS << "#endif // GET_SUBTARGETINFO_MC_DESC\n\n";
2074-
2075-
OS << "\n#ifdef GET_SUBTARGETINFO_TARGET_DESC\n";
2076-
OS << "#undef GET_SUBTARGETINFO_TARGET_DESC\n\n";
2066+
void SubtargetEmitter::emitTargetDesc(raw_ostream &OS) {
2067+
IfDefEmitter IfDef(OS, "GET_SUBTARGETINFO_TARGET_DESC");
20772068

20782069
OS << "#include \"llvm/ADT/BitmaskEnum.h\"\n";
20792070
OS << "#include \"llvm/Support/Debug.h\"\n";
20802071
OS << "#include \"llvm/Support/raw_ostream.h\"\n\n";
20812072
if (Target == "AArch64")
20822073
OS << "#include \"llvm/TargetParser/AArch64TargetParser.h\"\n\n";
20832074
parseFeaturesFunction(OS);
2075+
}
20842076

2085-
OS << "#endif // GET_SUBTARGETINFO_TARGET_DESC\n\n";
2086-
2077+
void SubtargetEmitter::emitHeader(raw_ostream &OS) {
20872078
// Create a TargetSubtargetInfo subclass to hide the MC layer initialization.
2088-
OS << "\n#ifdef GET_SUBTARGETINFO_HEADER\n";
2089-
OS << "#undef GET_SUBTARGETINFO_HEADER\n\n";
2079+
IfDefEmitter IfDef(OS, "GET_SUBTARGETINFO_HEADER");
2080+
NamespaceEmitter LLVMNS(OS, "llvm");
20902081

20912082
std::string ClassName = Target + "GenSubtargetInfo";
2092-
OS << "namespace llvm {\n";
20932083
OS << "class DFAPacketizer;\n";
2094-
OS << "namespace " << Target << "_MC {\n"
2095-
<< "unsigned resolveVariantSchedClassImpl(unsigned SchedClass,"
2096-
<< " const MCInst *MI, const MCInstrInfo *MCII, "
2097-
<< "const MCSubtargetInfo &STI, unsigned CPUID);\n"
2098-
<< "} // end namespace " << Target << "_MC\n\n";
2084+
{
2085+
NamespaceEmitter MCNS(OS, (Target + Twine("_MC")).str());
2086+
OS << "unsigned resolveVariantSchedClassImpl(unsigned SchedClass,"
2087+
<< " const MCInst *MI, const MCInstrInfo *MCII, "
2088+
<< "const MCSubtargetInfo &STI, unsigned CPUID);\n";
2089+
}
20992090
OS << "struct " << ClassName << " : public TargetSubtargetInfo {\n"
21002091
<< " explicit " << ClassName << "(const Triple &TT, StringRef CPU, "
21012092
<< "StringRef TuneCPU, StringRef FS);\n"
@@ -2140,17 +2131,15 @@ void SubtargetEmitter::run(raw_ostream &OS) {
21402131
PE.setByRef(false);
21412132
for (const STIPredicateFunction &Fn : SchedModels.getSTIPredicates())
21422133
PE.expandSTIPredicate(OS, Fn);
2134+
OS << "};\n";
2135+
}
21432136

2144-
OS << "};\n"
2145-
<< "} // end namespace llvm\n\n";
2146-
2147-
OS << "#endif // GET_SUBTARGETINFO_HEADER\n\n";
2148-
2149-
OS << "\n#ifdef GET_SUBTARGETINFO_CTOR\n";
2150-
OS << "#undef GET_SUBTARGETINFO_CTOR\n\n";
2151-
2137+
void SubtargetEmitter::emitCtor(raw_ostream &OS, unsigned NumNames,
2138+
unsigned NumFeatures, unsigned NumProcs) {
2139+
IfDefEmitter IfDef(OS, "GET_SUBTARGETINFO_CTOR");
21522140
OS << "#include \"llvm/CodeGen/TargetSchedule.h\"\n\n";
2153-
OS << "namespace llvm {\n";
2141+
2142+
NamespaceEmitter LLVMNS(OS, "llvm");
21542143
OS << "extern const llvm::StringRef " << Target << "Names[];\n";
21552144
OS << "extern const llvm::SubtargetFeatureKV " << Target << "FeatureKV[];\n";
21562145
OS << "extern const llvm::SubtargetSubTypeKV " << Target << "SubTypeKV[];\n";
@@ -2167,6 +2156,7 @@ void SubtargetEmitter::run(raw_ostream &OS) {
21672156
OS << "extern const unsigned " << Target << "ForwardingPaths[];\n";
21682157
}
21692158

2159+
std::string ClassName = Target + "GenSubtargetInfo";
21702160
OS << ClassName << "::" << ClassName << "(const Triple &TT, StringRef CPU, "
21712161
<< "StringRef TuneCPU, StringRef FS)\n";
21722162

@@ -2204,11 +2194,20 @@ void SubtargetEmitter::run(raw_ostream &OS) {
22042194
emitSchedModelHelpers(ClassName, OS);
22052195
emitHwModeCheck(ClassName, OS, /*IsMC=*/false);
22062196
emitGetMacroFusions(ClassName, OS);
2197+
}
22072198

2208-
OS << "} // end namespace llvm\n\n";
2209-
2210-
OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n";
2199+
//
2200+
// SubtargetEmitter::run - Main subtarget enumeration emitter.
2201+
//
2202+
void SubtargetEmitter::run(raw_ostream &OS) {
2203+
emitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
22112204

2205+
auto FeatureMap = emitEnums(OS);
2206+
emitSubtargetInfoMacroCalls(OS);
2207+
auto [NumNames, NumFeatures, NumProcs] = emitMCDesc(OS, FeatureMap);
2208+
emitTargetDesc(OS);
2209+
emitHeader(OS);
2210+
emitCtor(OS, NumNames, NumFeatures, NumProcs);
22122211
emitMcInstrAnalysisPredicateFunctions(OS);
22132212
}
22142213

0 commit comments

Comments
 (0)