diff options
| author | Reid Kleckner <rnk@google.com> | 2019-12-11 07:55:26 -0800 |
|---|---|---|
| committer | Reid Kleckner <rnk@google.com> | 2019-12-11 18:02:14 -0800 |
| commit | 5d986953c8b917bacfaa1f800fc1e242559f76be (patch) | |
| tree | 589c17071df77f5910a4d0c61c28ecb5a696a90a /llvm/utils/TableGen | |
| parent | 85ba5f637af83336151d31f83708128372a232c9 (diff) | |
| download | bcm5719-llvm-5d986953c8b917bacfaa1f800fc1e242559f76be.tar.gz bcm5719-llvm-5d986953c8b917bacfaa1f800fc1e242559f76be.zip | |
[IR] Split out target specific intrinsic enums into separate headers
This has two main effects:
- Optimizes debug info size by saving 221.86 MB of obj file size in a
Windows optimized+debug build of 'all'. This is 3.03% of 7,332.7MB of
object file size.
- Incremental step towards decoupling target intrinsics.
The enums are still compact, so adding and removing a single
target-specific intrinsic will trigger a rebuild of all of LLVM.
Assigning distinct target id spaces is potential future work.
Part of PR34259
Reviewers: efriedma, echristo, MaskRay
Reviewed By: echristo, MaskRay
Differential Revision: https://reviews.llvm.org/D71320
Diffstat (limited to 'llvm/utils/TableGen')
| -rw-r--r-- | llvm/utils/TableGen/IntrinsicEmitter.cpp | 76 |
1 files changed, 65 insertions, 11 deletions
diff --git a/llvm/utils/TableGen/IntrinsicEmitter.cpp b/llvm/utils/TableGen/IntrinsicEmitter.cpp index 7598c82682b..08002365736 100644 --- a/llvm/utils/TableGen/IntrinsicEmitter.cpp +++ b/llvm/utils/TableGen/IntrinsicEmitter.cpp @@ -15,14 +15,21 @@ #include "SequenceToOffsetTable.h" #include "TableGenBackends.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/Support/CommandLine.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" #include "llvm/TableGen/StringMatcher.h" -#include "llvm/TableGen/TableGenBackend.h" #include "llvm/TableGen/StringToOffsetTable.h" +#include "llvm/TableGen/TableGenBackend.h" #include <algorithm> using namespace llvm; +cl::OptionCategory GenIntrinsicCat("Options for -gen-intrinsic-enums"); +cl::opt<std::string> + IntrinsicPrefix("intrinsic-prefix", + cl::desc("Generate intrinsics with this target prefix"), + cl::value_desc("target prefix"), cl::cat(GenIntrinsicCat)); + namespace { class IntrinsicEmitter { RecordKeeper &Records; @@ -57,12 +64,12 @@ void IntrinsicEmitter::run(raw_ostream &OS, bool Enums) { CodeGenIntrinsicTable Ints(Records); - EmitPrefix(OS); - if (Enums) { // Emit the enum information. EmitEnumInfo(Ints, OS); } else { + EmitPrefix(OS); + // Emit the target metadata. EmitTargetInfo(Ints, OS); @@ -83,9 +90,9 @@ void IntrinsicEmitter::run(raw_ostream &OS, bool Enums) { // Emit code to translate MS builtins into LLVM intrinsics. EmitIntrinsicToBuiltinMap(Ints, false, OS); - } - EmitSuffix(OS); + EmitSuffix(OS); + } } void IntrinsicEmitter::EmitPrefix(raw_ostream &OS) { @@ -108,16 +115,63 @@ void IntrinsicEmitter::EmitSuffix(raw_ostream &OS) { void IntrinsicEmitter::EmitEnumInfo(const CodeGenIntrinsicTable &Ints, raw_ostream &OS) { - OS << "// Enum values for Intrinsics.h\n"; - OS << "#ifdef GET_INTRINSIC_ENUM_VALUES\n"; - for (unsigned i = 0, e = Ints.size(); i != e; ++i) { + // Find the TargetSet for which to generate enums. There will be an initial + // set with an empty target prefix which will include target independent + // intrinsics like dbg.value. + const CodeGenIntrinsicTable::TargetSet *Set = nullptr; + for (const auto &Target : Ints.Targets) { + if (Target.Name == IntrinsicPrefix) { + Set = &Target; + break; + } + } + if (!Set) { + std::vector<std::string> KnownTargets; + for (const auto &Target : Ints.Targets) + if (!Target.Name.empty()) + KnownTargets.push_back(Target.Name); + PrintFatalError("tried to generate intrinsics for unknown target " + + IntrinsicPrefix + + "\nKnown targets are: " + join(KnownTargets, ", ") + "\n"); + } + + // Generate a complete header for target specific intrinsics. + if (!IntrinsicPrefix.empty()) { + std::string UpperPrefix = StringRef(IntrinsicPrefix).upper(); + OS << "#ifndef LLVM_IR_INTRINSIC_" << UpperPrefix << "_ENUMS_H\n"; + OS << "#define LLVM_IR_INTRINSIC_" << UpperPrefix << "_ENUMS_H\n\n"; + OS << "namespace llvm {\n"; + OS << "namespace Intrinsic {\n"; + OS << "enum " << UpperPrefix << "Intrinsics : unsigned {\n"; + } else { + EmitPrefix(OS); + } + + OS << "// Enum values for intrinsics\n"; + for (unsigned i = Set->Offset, e = Set->Offset + Set->Count; i != e; ++i) { OS << " " << Ints[i].EnumName; - OS << ((i != e-1) ? ", " : " "); + + // Assign a value to the first intrinsic in this target set so that all + // intrinsic ids are distinct. + if (i == Set->Offset) + OS << " = " << (Set->Offset + 1); + + OS << ", "; if (Ints[i].EnumName.size() < 40) - OS << std::string(40-Ints[i].EnumName.size(), ' '); + OS.indent(40 - Ints[i].EnumName.size()); OS << " // " << Ints[i].Name << "\n"; } - OS << "#endif\n\n"; + + // Emit num_intrinsics into the target neutral enum. + if (IntrinsicPrefix.empty()) { + OS << " num_intrinsics = " << (Ints.size() + 1) << "\n"; + EmitSuffix(OS); + } else { + OS << "}; // enum\n"; + OS << "} // namespace Intrinsic\n"; + OS << "} // namespace llvm\n\n"; + OS << "#endif\n"; + } } void IntrinsicEmitter::EmitTargetInfo(const CodeGenIntrinsicTable &Ints, |

