summaryrefslogtreecommitdiffstats
path: root/llvm/utils/TableGen
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2019-12-11 07:55:26 -0800
committerReid Kleckner <rnk@google.com>2019-12-11 18:02:14 -0800
commit5d986953c8b917bacfaa1f800fc1e242559f76be (patch)
tree589c17071df77f5910a4d0c61c28ecb5a696a90a /llvm/utils/TableGen
parent85ba5f637af83336151d31f83708128372a232c9 (diff)
downloadbcm5719-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.cpp76
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,
OpenPOWER on IntegriCloud