-
Notifications
You must be signed in to change notification settings - Fork 15k
[NFC][TableGen] Adopt CodeGenHelpers in SubtargetEmitter #163820
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jurahul
wants to merge
2
commits into
llvm:main
Choose a base branch
from
jurahul:nfc_adropt_ifdef_ns_emitter_subtarget_emitter
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
[NFC][TableGen] Adopt CodeGenHelpers in SubtargetEmitter #163820
jurahul
wants to merge
2
commits into
llvm:main
from
jurahul:nfc_adropt_ifdef_ns_emitter_subtarget_emitter
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3d63762 to
f6ae047
Compare
topperc
reviewed
Oct 16, 2025
f6ae047 to
842a131
Compare
b2d599b to
23fd850
Compare
|
@llvm/pr-subscribers-tablegen Author: Rahul Joshi (jurahul) Changes
Full diff: https://github.com/llvm/llvm-project/pull/163820.diff 2 Files Affected:
diff --git a/llvm/include/llvm/TableGen/CodeGenHelpers.h b/llvm/include/llvm/TableGen/CodeGenHelpers.h
index e22c6d4f6d390..053f7e4aab866 100644
--- a/llvm/include/llvm/TableGen/CodeGenHelpers.h
+++ b/llvm/include/llvm/TableGen/CodeGenHelpers.h
@@ -20,18 +20,37 @@
#include <string>
namespace llvm {
-// Simple RAII helper for emitting ifdef-undef-endif scope.
+// Simple RAII helper for emitting ifdef-undef-endif scope. `LateUndef` controls
+// whether the undef is emitted at the start of the scope (false) or at the end
+// of the scope (true).
class IfDefEmitter {
public:
- IfDefEmitter(raw_ostream &OS, StringRef Name) : Name(Name.str()), OS(OS) {
- OS << "#ifdef " << Name << "\n"
- << "#undef " << Name << "\n\n";
+ IfDefEmitter(raw_ostream &OS, StringRef Name, bool LateUndef = false)
+ : Name(Name.str()), OS(OS), LateUndef(LateUndef) {
+ OS << "#ifdef " << Name << "\n";
+ if (!LateUndef)
+ OS << "#undef " << Name << "\n";
+ OS << "\n";
+ }
+ ~IfDefEmitter() { close(); }
+
+ // Explicit function to close the ifdef scopes.
+ void close() {
+ if (Closed)
+ return;
+
+ OS << "\n";
+ if (LateUndef)
+ OS << "#undef " << Name << "\n";
+ OS << "#endif // " << Name << "\n\n";
+ Closed = true;
}
- ~IfDefEmitter() { OS << "\n#endif // " << Name << "\n\n"; }
private:
std::string Name;
raw_ostream &OS;
+ bool LateUndef;
+ bool Closed = false;
};
// Simple RAII helper for emitting header include guard (ifndef-define-endif).
@@ -42,11 +61,20 @@ class IncludeGuardEmitter {
OS << "#ifndef " << Name << "\n"
<< "#define " << Name << "\n\n";
}
- ~IncludeGuardEmitter() { OS << "\n#endif // " << Name << "\n"; }
+ ~IncludeGuardEmitter() { close(); }
+
+ // Explicit function to close the ifdef scopes.
+ void close() {
+ if (Closed)
+ return;
+ OS << "\n#endif // " << Name << "\n\n";
+ Closed = true;
+ }
private:
std::string Name;
raw_ostream &OS;
+ bool Closed = false;
};
// Simple RAII helper for emitting namespace scope. Name can be a single
@@ -64,7 +92,9 @@ class NamespaceEmitter {
// Explicit function to close the namespace scopes.
void close() {
- if (!Closed && !Name.empty())
+ if (Closed)
+ return;
+ if (!Name.empty())
OS << "} // namespace " << Name << "\n";
Closed = true;
}
diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp
index 2f15cc8c76548..c3fb089d3f608 100644
--- a/llvm/utils/TableGen/SubtargetEmitter.cpp
+++ b/llvm/utils/TableGen/SubtargetEmitter.cpp
@@ -27,6 +27,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/TableGen/CodeGenHelpers.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/StringToOffsetTable.h"
@@ -75,7 +76,15 @@ class SubtargetEmitter : TargetFeaturesEmitter {
CodeGenTarget TGT;
CodeGenSchedModels &SchedModels;
+ FeatureMapTy emitEnums(raw_ostream &OS);
void emitSubtargetInfoMacroCalls(raw_ostream &OS);
+ std::tuple<unsigned, unsigned, unsigned>
+ emitMCDesc(raw_ostream &OS, const FeatureMapTy &FeatureMap);
+ void emitTargetDesc(raw_ostream &OS);
+ void emitHeader(raw_ostream &OS);
+ void emitCtor(raw_ostream &OS, unsigned NumNames, unsigned NumFeatures,
+ unsigned NumProcs);
+
unsigned featureKeyValues(raw_ostream &OS, const FeatureMapTy &FeatureMap);
unsigned cpuKeyValues(raw_ostream &OS, const FeatureMapTy &FeatureMap);
unsigned cpuNames(raw_ostream &OS);
@@ -141,7 +150,9 @@ class SubtargetEmitter : TargetFeaturesEmitter {
/// Emit some information about the SubtargetFeature as calls to a macro so
/// that they can be used from C++.
void SubtargetEmitter::emitSubtargetInfoMacroCalls(raw_ostream &OS) {
- OS << "\n#ifdef GET_SUBTARGETINFO_MACRO\n";
+ // Undef the GET_SUBTARGETINFO_MACRO macro at the end of the scope since its
+ // used within the scope.
+ IfDefEmitter IfDefMacro(OS, "GET_SUBTARGETINFO_MACRO", /*LateUndef=*/true);
std::vector<const Record *> FeatureList =
Records.getAllDerivedDefinitions("SubtargetFeature");
@@ -167,14 +178,6 @@ void SubtargetEmitter::emitSubtargetInfoMacroCalls(raw_ostream &OS) {
OS << "GET_SUBTARGETINFO_MACRO(" << FieldName << ", " << Default << ", "
<< Getter << ")\n";
}
- OS << "#undef GET_SUBTARGETINFO_MACRO\n";
- OS << "#endif // GET_SUBTARGETINFO_MACRO\n\n";
-
- OS << "\n#ifdef GET_SUBTARGETINFO_MC_DESC\n";
- OS << "#undef GET_SUBTARGETINFO_MC_DESC\n\n";
-
- if (Target == "AArch64")
- OS << "#include \"llvm/TargetParser/AArch64TargetParser.h\"\n\n";
}
//
@@ -440,26 +443,24 @@ void SubtargetEmitter::emitStageAndOperandCycleData(
continue;
StringRef Name = ProcModel.ItinsDef->getName();
- OS << "\n// Functional units for \"" << Name << "\"\n"
- << "namespace " << Name << "FU {\n";
+ OS << "\n// Functional units for \"" << Name << "\"\n";
+ NamespaceEmitter FUNamespace(OS, (Name + Twine("FU")).str());
for (const auto &[Idx, FU] : enumerate(FUs))
OS << " const InstrStage::FuncUnits " << FU->getName() << " = 1ULL << "
<< Idx << ";\n";
- OS << "} // end namespace " << Name << "FU\n";
+ FUNamespace.close();
ConstRecVec BPs = ProcModel.ItinsDef->getValueAsListOfDefs("BP");
if (BPs.empty())
continue;
- OS << "\n// Pipeline forwarding paths for itineraries \"" << Name << "\"\n"
- << "namespace " << Name << "Bypass {\n";
+ OS << "\n// Pipeline forwarding paths for itineraries \"" << Name << "\"\n";
+ NamespaceEmitter BypassNamespace(OS, (Name + Twine("Bypass")).str());
OS << " const unsigned NoBypass = 0;\n";
for (const auto &[Idx, BP] : enumerate(BPs))
OS << " const unsigned " << BP->getName() << " = 1 << " << Idx << ";\n";
-
- OS << "} // end namespace " << Name << "Bypass\n";
}
// Begin stages table
@@ -1940,13 +1941,13 @@ void SubtargetEmitter::parseFeaturesFunction(raw_ostream &OS) {
}
void SubtargetEmitter::emitGenMCSubtargetInfo(raw_ostream &OS) {
- OS << "namespace " << Target << "_MC {\n"
- << "unsigned resolveVariantSchedClassImpl(unsigned SchedClass,\n"
+ NamespaceEmitter NS(OS, (Target + Twine("_MC")).str());
+ OS << "unsigned resolveVariantSchedClassImpl(unsigned SchedClass,\n"
<< " const MCInst *MI, const MCInstrInfo *MCII, "
<< "const MCSubtargetInfo &STI, unsigned CPUID) {\n";
emitSchedModelHelpersImpl(OS, /* OnlyExpandMCPredicates */ true);
OS << "}\n";
- OS << "} // end namespace " << Target << "_MC\n\n";
+ NS.close();
OS << "struct " << Target
<< "GenMCSubtargetInfo : public MCSubtargetInfo {\n";
@@ -1982,8 +1983,7 @@ void SubtargetEmitter::emitGenMCSubtargetInfo(raw_ostream &OS) {
}
void SubtargetEmitter::emitMcInstrAnalysisPredicateFunctions(raw_ostream &OS) {
- OS << "\n#ifdef GET_STIPREDICATE_DECLS_FOR_MC_ANALYSIS\n";
- OS << "#undef GET_STIPREDICATE_DECLS_FOR_MC_ANALYSIS\n\n";
+ IfDefEmitter IfDefDecls(OS, "GET_STIPREDICATE_DECLS_FOR_MC_ANALYSIS");
STIPredicateExpander PE(Target, /*Indent=*/0);
PE.setExpandForMC(true);
@@ -1991,37 +1991,29 @@ void SubtargetEmitter::emitMcInstrAnalysisPredicateFunctions(raw_ostream &OS) {
for (const STIPredicateFunction &Fn : SchedModels.getSTIPredicates())
PE.expandSTIPredicate(OS, Fn);
- OS << "#endif // GET_STIPREDICATE_DECLS_FOR_MC_ANALYSIS\n\n";
-
- OS << "\n#ifdef GET_STIPREDICATE_DEFS_FOR_MC_ANALYSIS\n";
- OS << "#undef GET_STIPREDICATE_DEFS_FOR_MC_ANALYSIS\n\n";
+ IfDefDecls.close();
+ IfDefEmitter IfDefDefs(OS, "GET_STIPREDICATE_DEFS_FOR_MC_ANALYSIS");
std::string ClassPrefix = Target + "MCInstrAnalysis";
PE.setExpandDefinition(true);
PE.setClassPrefix(ClassPrefix);
for (const STIPredicateFunction &Fn : SchedModels.getSTIPredicates())
PE.expandSTIPredicate(OS, Fn);
-
- OS << "#endif // GET_STIPREDICATE_DEFS_FOR_MC_ANALYSIS\n\n";
}
-//
-// SubtargetEmitter::run - Main subtarget enumeration emitter.
-//
-void SubtargetEmitter::run(raw_ostream &OS) {
- emitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
-
- OS << "\n#ifdef GET_SUBTARGETINFO_ENUM\n";
- OS << "#undef GET_SUBTARGETINFO_ENUM\n\n";
-
- OS << "namespace llvm {\n";
- auto FeatureMap = enumeration(OS);
- OS << "} // end namespace llvm\n\n";
- OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n";
+FeatureMapTy SubtargetEmitter::emitEnums(raw_ostream &OS) {
+ IfDefEmitter IfDef(OS, "GET_SUBTARGETINFO_ENUM");
+ NamespaceEmitter NS(OS, "llvm");
+ return enumeration(OS);
+}
- emitSubtargetInfoMacroCalls(OS);
+std::tuple<unsigned, unsigned, unsigned>
+SubtargetEmitter::emitMCDesc(raw_ostream &OS, const FeatureMapTy &FeatureMap) {
+ IfDefEmitter IfDef(OS, "GET_SUBTARGETINFO_MC_DESC");
+ if (Target == "AArch64")
+ OS << "#include \"llvm/TargetParser/AArch64TargetParser.h\"\n\n";
+ NamespaceEmitter LlvmNS(OS, "llvm");
- OS << "namespace llvm {\n";
unsigned NumFeatures = featureKeyValues(OS, FeatureMap);
OS << "\n";
emitSchedModel(OS);
@@ -2067,13 +2059,11 @@ void SubtargetEmitter::run(raw_ostream &OS) {
OS << "nullptr, nullptr, nullptr";
}
OS << ");\n}\n\n";
+ return {NumNames, NumFeatures, NumProcs};
+}
- OS << "} // end namespace llvm\n\n";
-
- OS << "#endif // GET_SUBTARGETINFO_MC_DESC\n\n";
-
- OS << "\n#ifdef GET_SUBTARGETINFO_TARGET_DESC\n";
- OS << "#undef GET_SUBTARGETINFO_TARGET_DESC\n\n";
+void SubtargetEmitter::emitTargetDesc(raw_ostream &OS) {
+ IfDefEmitter IfDef(OS, "GET_SUBTARGETINFO_TARGET_DESC");
OS << "#include \"llvm/ADT/BitmaskEnum.h\"\n";
OS << "#include \"llvm/Support/Debug.h\"\n";
@@ -2081,21 +2071,21 @@ void SubtargetEmitter::run(raw_ostream &OS) {
if (Target == "AArch64")
OS << "#include \"llvm/TargetParser/AArch64TargetParser.h\"\n\n";
parseFeaturesFunction(OS);
+}
- OS << "#endif // GET_SUBTARGETINFO_TARGET_DESC\n\n";
-
+void SubtargetEmitter::emitHeader(raw_ostream &OS) {
// Create a TargetSubtargetInfo subclass to hide the MC layer initialization.
- OS << "\n#ifdef GET_SUBTARGETINFO_HEADER\n";
- OS << "#undef GET_SUBTARGETINFO_HEADER\n\n";
+ IfDefEmitter IfDef(OS, "GET_SUBTARGETINFO_HEADER");
+ NamespaceEmitter LLVMNS(OS, "llvm");
std::string ClassName = Target + "GenSubtargetInfo";
- OS << "namespace llvm {\n";
OS << "class DFAPacketizer;\n";
- OS << "namespace " << Target << "_MC {\n"
- << "unsigned resolveVariantSchedClassImpl(unsigned SchedClass,"
- << " const MCInst *MI, const MCInstrInfo *MCII, "
- << "const MCSubtargetInfo &STI, unsigned CPUID);\n"
- << "} // end namespace " << Target << "_MC\n\n";
+ {
+ NamespaceEmitter MCNS(OS, (Target + Twine("_MC")).str());
+ OS << "unsigned resolveVariantSchedClassImpl(unsigned SchedClass,"
+ << " const MCInst *MI, const MCInstrInfo *MCII, "
+ << "const MCSubtargetInfo &STI, unsigned CPUID);\n";
+ }
OS << "struct " << ClassName << " : public TargetSubtargetInfo {\n"
<< " explicit " << ClassName << "(const Triple &TT, StringRef CPU, "
<< "StringRef TuneCPU, StringRef FS);\n"
@@ -2140,17 +2130,15 @@ void SubtargetEmitter::run(raw_ostream &OS) {
PE.setByRef(false);
for (const STIPredicateFunction &Fn : SchedModels.getSTIPredicates())
PE.expandSTIPredicate(OS, Fn);
+ OS << "};\n";
+}
- OS << "};\n"
- << "} // end namespace llvm\n\n";
-
- OS << "#endif // GET_SUBTARGETINFO_HEADER\n\n";
-
- OS << "\n#ifdef GET_SUBTARGETINFO_CTOR\n";
- OS << "#undef GET_SUBTARGETINFO_CTOR\n\n";
-
+void SubtargetEmitter::emitCtor(raw_ostream &OS, unsigned NumNames,
+ unsigned NumFeatures, unsigned NumProcs) {
+ IfDefEmitter IfDef(OS, "GET_SUBTARGETINFO_CTOR");
OS << "#include \"llvm/CodeGen/TargetSchedule.h\"\n\n";
- OS << "namespace llvm {\n";
+
+ NamespaceEmitter LLVMNS(OS, "llvm");
OS << "extern const llvm::StringRef " << Target << "Names[];\n";
OS << "extern const llvm::SubtargetFeatureKV " << Target << "FeatureKV[];\n";
OS << "extern const llvm::SubtargetSubTypeKV " << Target << "SubTypeKV[];\n";
@@ -2167,6 +2155,7 @@ void SubtargetEmitter::run(raw_ostream &OS) {
OS << "extern const unsigned " << Target << "ForwardingPaths[];\n";
}
+ std::string ClassName = Target + "GenSubtargetInfo";
OS << ClassName << "::" << ClassName << "(const Triple &TT, StringRef CPU, "
<< "StringRef TuneCPU, StringRef FS)\n";
@@ -2204,11 +2193,20 @@ void SubtargetEmitter::run(raw_ostream &OS) {
emitSchedModelHelpers(ClassName, OS);
emitHwModeCheck(ClassName, OS, /*IsMC=*/false);
emitGetMacroFusions(ClassName, OS);
+}
- OS << "} // end namespace llvm\n\n";
-
- OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n";
+//
+// SubtargetEmitter::run - Main subtarget enumeration emitter.
+//
+void SubtargetEmitter::run(raw_ostream &OS) {
+ emitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
+ auto FeatureMap = emitEnums(OS);
+ emitSubtargetInfoMacroCalls(OS);
+ auto [NumNames, NumFeatures, NumProcs] = emitMCDesc(OS, FeatureMap);
+ emitTargetDesc(OS);
+ emitHeader(OS);
+ emitCtor(OS, NumNames, NumFeatures, NumProcs);
emitMcInstrAnalysisPredicateFunctions(OS);
}
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.