Skip to content

Commit b279435

Browse files
committed
[NFC][TableGen] Adopt CodeGenHelpers in SubtargetEmitter
1 parent 4f428d3 commit b279435

File tree

2 files changed

+105
-77
lines changed

2 files changed

+105
-77
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: 68 additions & 70 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 and the end of the scope since its
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";
446+
OS << "\n// Functional units for \"" << Name << "\"\n";
447+
NamespaceEmitter FUNamespace(OS, (Name + Twine("FU")).str());
445448

446449
for (const auto &[Idx, FU] : enumerate(FUs))
447450
OS << " const InstrStage::FuncUnits " << FU->getName() << " = 1ULL << "
448451
<< Idx << ";\n";
449452

450-
OS << "} // end namespace " << Name << "FU\n";
453+
FUNamespace.close();
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,13 @@ 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"
1944+
NamespaceEmitter NS(OS, (Target + Twine("_MC")).str());
1945+
OS << "unsigned resolveVariantSchedClassImpl(unsigned SchedClass,\n"
19451946
<< " const MCInst *MI, const MCInstrInfo *MCII, "
19461947
<< "const MCSubtargetInfo &STI, unsigned CPUID) {\n";
19471948
emitSchedModelHelpersImpl(OS, /* OnlyExpandMCPredicates */ true);
19481949
OS << "}\n";
1949-
OS << "} // end namespace " << Target << "_MC\n\n";
1950+
NS.close();
19501951

19511952
OS << "struct " << Target
19521953
<< "GenMCSubtargetInfo : public MCSubtargetInfo {\n";
@@ -1982,46 +1983,37 @@ void SubtargetEmitter::emitGenMCSubtargetInfo(raw_ostream &OS) {
19821983
}
19831984

19841985
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";
1986+
IfDefEmitter IfDefDecls(OS, "GET_STIPREDICATE_DECLS_FOR_MC_ANALYSIS");
19871987

19881988
STIPredicateExpander PE(Target, /*Indent=*/0);
19891989
PE.setExpandForMC(true);
19901990
PE.setByRef(true);
19911991
for (const STIPredicateFunction &Fn : SchedModels.getSTIPredicates())
19921992
PE.expandSTIPredicate(OS, Fn);
19931993

1994-
OS << "#endif // GET_STIPREDICATE_DECLS_FOR_MC_ANALYSIS\n\n";
1995-
1996-
OS << "\n#ifdef GET_STIPREDICATE_DEFS_FOR_MC_ANALYSIS\n";
1997-
OS << "#undef GET_STIPREDICATE_DEFS_FOR_MC_ANALYSIS\n\n";
1994+
IfDefDecls.close();
19981995

1996+
IfDefEmitter IfDefDefs(OS, "GET_STIPREDICATE_DEFS_FOR_MC_ANALYSIS");
19991997
std::string ClassPrefix = Target + "MCInstrAnalysis";
20001998
PE.setExpandDefinition(true);
20011999
PE.setClassPrefix(ClassPrefix);
20022000
for (const STIPredicateFunction &Fn : SchedModels.getSTIPredicates())
20032001
PE.expandSTIPredicate(OS, Fn);
2004-
2005-
OS << "#endif // GET_STIPREDICATE_DEFS_FOR_MC_ANALYSIS\n\n";
20062002
}
20072003

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";
2004+
FeatureMapTy SubtargetEmitter::emitEnums(raw_ostream &OS) {
2005+
IfDefEmitter IfDef(OS, "GET_SUBTARGETINFO_ENUM");
2006+
NamespaceEmitter NS(OS, "llvm");
2007+
return enumeration(OS);
2008+
}
20212009

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

2024-
OS << "namespace llvm {\n";
20252017
unsigned NumFeatures = featureKeyValues(OS, FeatureMap);
20262018
OS << "\n";
20272019
emitSchedModel(OS);
@@ -2067,35 +2059,33 @@ void SubtargetEmitter::run(raw_ostream &OS) {
20672059
OS << "nullptr, nullptr, nullptr";
20682060
}
20692061
OS << ");\n}\n\n";
2062+
return {NumNames, NumFeatures, NumProcs};
2063+
}
20702064

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";
2065+
void SubtargetEmitter::emitTargetDesc(raw_ostream &OS) {
2066+
IfDefEmitter IfDef(OS, "GET_SUBTARGETINFO_TARGET_DESC");
20772067

20782068
OS << "#include \"llvm/ADT/BitmaskEnum.h\"\n";
20792069
OS << "#include \"llvm/Support/Debug.h\"\n";
20802070
OS << "#include \"llvm/Support/raw_ostream.h\"\n\n";
20812071
if (Target == "AArch64")
20822072
OS << "#include \"llvm/TargetParser/AArch64TargetParser.h\"\n\n";
20832073
parseFeaturesFunction(OS);
2074+
}
20842075

2085-
OS << "#endif // GET_SUBTARGETINFO_TARGET_DESC\n\n";
2086-
2076+
void SubtargetEmitter::emitHeader(raw_ostream &OS) {
20872077
// 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";
2078+
IfDefEmitter IfDef(OS, "GET_SUBTARGETINFO_HEADER");
2079+
NamespaceEmitter LLVMNS(OS, "llvm");
20902080

20912081
std::string ClassName = Target + "GenSubtargetInfo";
2092-
OS << "namespace llvm {\n";
20932082
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";
2083+
{
2084+
NamespaceEmitter MCNS(OS, (Target + Twine("_MC")).str());
2085+
OS << "unsigned resolveVariantSchedClassImpl(unsigned SchedClass,"
2086+
<< " const MCInst *MI, const MCInstrInfo *MCII, "
2087+
<< "const MCSubtargetInfo &STI, unsigned CPUID);\n";
2088+
}
20992089
OS << "struct " << ClassName << " : public TargetSubtargetInfo {\n"
21002090
<< " explicit " << ClassName << "(const Triple &TT, StringRef CPU, "
21012091
<< "StringRef TuneCPU, StringRef FS);\n"
@@ -2140,17 +2130,15 @@ void SubtargetEmitter::run(raw_ostream &OS) {
21402130
PE.setByRef(false);
21412131
for (const STIPredicateFunction &Fn : SchedModels.getSTIPredicates())
21422132
PE.expandSTIPredicate(OS, Fn);
2133+
OS << "};\n";
2134+
}
21432135

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-
2136+
void SubtargetEmitter::emitCtor(raw_ostream &OS, unsigned NumNames,
2137+
unsigned NumFeatures, unsigned NumProcs) {
2138+
IfDefEmitter IfDef(OS, "GET_SUBTARGETINFO_CTOR");
21522139
OS << "#include \"llvm/CodeGen/TargetSchedule.h\"\n\n";
2153-
OS << "namespace llvm {\n";
2140+
2141+
NamespaceEmitter LLVMNS(OS, "llvm");
21542142
OS << "extern const llvm::StringRef " << Target << "Names[];\n";
21552143
OS << "extern const llvm::SubtargetFeatureKV " << Target << "FeatureKV[];\n";
21562144
OS << "extern const llvm::SubtargetSubTypeKV " << Target << "SubTypeKV[];\n";
@@ -2167,6 +2155,7 @@ void SubtargetEmitter::run(raw_ostream &OS) {
21672155
OS << "extern const unsigned " << Target << "ForwardingPaths[];\n";
21682156
}
21692157

2158+
std::string ClassName = Target + "GenSubtargetInfo";
21702159
OS << ClassName << "::" << ClassName << "(const Triple &TT, StringRef CPU, "
21712160
<< "StringRef TuneCPU, StringRef FS)\n";
21722161

@@ -2204,11 +2193,20 @@ void SubtargetEmitter::run(raw_ostream &OS) {
22042193
emitSchedModelHelpers(ClassName, OS);
22052194
emitHwModeCheck(ClassName, OS, /*IsMC=*/false);
22062195
emitGetMacroFusions(ClassName, OS);
2196+
}
22072197

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

2204+
auto FeatureMap = emitEnums(OS);
2205+
emitSubtargetInfoMacroCalls(OS);
2206+
auto [NumNames, NumFeatures, NumProcs] = emitMCDesc(OS, FeatureMap);
2207+
emitTargetDesc(OS);
2208+
emitHeader(OS);
2209+
emitCtor(OS, NumNames, NumFeatures, NumProcs);
22122210
emitMcInstrAnalysisPredicateFunctions(OS);
22132211
}
22142212

0 commit comments

Comments
 (0)