[llvm] r258897 - [llvm-tblgen] Avoid StringMatcher for GCC and MS builtin names
Reid Kleckner via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 26 17:43:12 PST 2016
Author: rnk
Date: Tue Jan 26 19:43:12 2016
New Revision: 258897
URL: http://llvm.org/viewvc/llvm-project?rev=258897&view=rev
Log:
[llvm-tblgen] Avoid StringMatcher for GCC and MS builtin names
This brings the compile time of Function.cpp from ~40s down to ~4s for
me locally. It also shaves off about 400KB of object file size in a
release+asserts build.
I also realized that the AMDGPU backend does not have any GCC builtin
names to match, so the extra lookup was a no-op. I removed it to silence
a zero-length string table array warning. There should be no functional
change here.
This change really ends the story of PR11951.
Modified:
llvm/trunk/include/llvm/TableGen/StringToOffsetTable.h
llvm/trunk/lib/Target/AMDGPU/AMDGPUIntrinsicInfo.cpp
llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp
Modified: llvm/trunk/include/llvm/TableGen/StringToOffsetTable.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/TableGen/StringToOffsetTable.h?rev=258897&r1=258896&r2=258897&view=diff
==============================================================================
--- llvm/trunk/include/llvm/TableGen/StringToOffsetTable.h (original)
+++ llvm/trunk/include/llvm/TableGen/StringToOffsetTable.h Tue Jan 26 19:43:12 2016
@@ -76,6 +76,26 @@ public:
}
O << "\"";
}
+
+ /// Emit the string using character literals. MSVC has a limitation that
+ /// string literals cannot be longer than 64K.
+ void EmitCharArray(raw_ostream &O) {
+ assert(AggregateString.find(')') == std::string::npos &&
+ "can't emit raw string with closing parens");
+ int Count = 0;
+ O << ' ';
+ for (char C : AggregateString) {
+ O << " \'";
+ O.write_escaped(StringRef(&C, 1));
+ O << "\',";
+ Count++;
+ if (Count > 14) {
+ O << "\n ";
+ Count = 0;
+ }
+ }
+ O << '\n';
+ }
};
} // end namespace llvm
Modified: llvm/trunk/lib/Target/AMDGPU/AMDGPUIntrinsicInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AMDGPUIntrinsicInfo.cpp?rev=258897&r1=258896&r2=258897&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/AMDGPUIntrinsicInfo.cpp (original)
+++ llvm/trunk/lib/Target/AMDGPU/AMDGPUIntrinsicInfo.cpp Tue Jan 26 19:43:12 2016
@@ -20,10 +20,6 @@
using namespace llvm;
-#define GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
-#include "AMDGPUGenIntrinsics.inc"
-#undef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
-
AMDGPUIntrinsicInfo::AMDGPUIntrinsicInfo()
: TargetIntrinsicInfo() {}
@@ -62,8 +58,7 @@ unsigned AMDGPUIntrinsicInfo::lookupName
: 0;
}
- // Fall back on GCC builtin names.
- return getIntrinsicForGCCBuiltin("AMDGPU", NameData);
+ return 0;
}
bool AMDGPUIntrinsicInfo::isOverloaded(unsigned id) const {
Modified: llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp?rev=258897&r1=258896&r2=258897&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp Tue Jan 26 19:43:12 2016
@@ -20,6 +20,7 @@
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/StringMatcher.h"
#include "llvm/TableGen/TableGenBackend.h"
+#include "llvm/TableGen/StringToOffsetTable.h"
#include <algorithm>
using namespace llvm;
@@ -48,10 +49,8 @@ public:
raw_ostream &OS);
void EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints,
raw_ostream &OS);
- void EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
- raw_ostream &OS);
- void EmitIntrinsicToMSBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
- raw_ostream &OS);
+ void EmitIntrinsicToBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
+ bool IsGCC, raw_ostream &OS);
void EmitSuffix(raw_ostream &OS);
};
} // End anonymous namespace
@@ -85,11 +84,14 @@ void IntrinsicEmitter::run(raw_ostream &
// Emit the intrinsic parameter attributes.
EmitAttributes(Ints, OS);
- // Emit code to translate GCC builtins into LLVM intrinsics.
- EmitIntrinsicToGCCBuiltinMap(Ints, OS);
+ // Individual targets don't need GCC builtin name mappings.
+ if (!TargetOnly) {
+ // Emit code to translate GCC builtins into LLVM intrinsics.
+ EmitIntrinsicToBuiltinMap(Ints, true, OS);
- // Emit code to translate MS builtins into LLVM intrinsics.
- EmitIntrinsicToMSBuiltinMap(Ints, OS);
+ // Emit code to translate MS builtins into LLVM intrinsics.
+ EmitIntrinsicToBuiltinMap(Ints, false, OS);
+ }
EmitSuffix(OS);
}
@@ -644,56 +646,57 @@ EmitAttributes(const std::vector<CodeGen
OS << "#endif // GET_INTRINSIC_ATTRIBUTES\n\n";
}
-/// EmitTargetBuiltins - All of the builtins in the specified map are for the
-/// same target, and we already checked it.
-static void EmitTargetBuiltins(const std::map<std::string, std::string> &BIM,
- const std::string &TargetPrefix,
- raw_ostream &OS) {
-
- std::vector<StringMatcher::StringPair> Results;
-
- for (std::map<std::string, std::string>::const_iterator I = BIM.begin(),
- E = BIM.end(); I != E; ++I) {
- std::string ResultCode =
- "return " + TargetPrefix + "Intrinsic::" + I->second + ";";
- Results.emplace_back(I->first, ResultCode);
- }
-
- StringMatcher("BuiltinName", Results, OS).Emit();
-}
-
-
-void IntrinsicEmitter::
-EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
- raw_ostream &OS) {
- typedef std::map<std::string, std::map<std::string, std::string> > BIMTy;
+void IntrinsicEmitter::EmitIntrinsicToBuiltinMap(
+ const std::vector<CodeGenIntrinsic> &Ints, bool IsGCC, raw_ostream &OS) {
+ StringRef CompilerName = (IsGCC ? "GCC" : "MS");
+ typedef std::map<std::string, std::map<std::string, std::string>> BIMTy;
BIMTy BuiltinMap;
+ StringToOffsetTable Table;
for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
- if (!Ints[i].GCCBuiltinName.empty()) {
+ const std::string &BuiltinName =
+ IsGCC ? Ints[i].GCCBuiltinName : Ints[i].MSBuiltinName;
+ if (!BuiltinName.empty()) {
// Get the map for this target prefix.
- std::map<std::string, std::string> &BIM =BuiltinMap[Ints[i].TargetPrefix];
+ std::map<std::string, std::string> &BIM =
+ BuiltinMap[Ints[i].TargetPrefix];
- if (!BIM.insert(std::make_pair(Ints[i].GCCBuiltinName,
- Ints[i].EnumName)).second)
+ if (!BIM.insert(std::make_pair(BuiltinName, Ints[i].EnumName)).second)
PrintFatalError("Intrinsic '" + Ints[i].TheDef->getName() +
- "': duplicate GCC builtin name!");
+ "': duplicate " + CompilerName + " builtin name!");
+ Table.GetOrAddStringOffset(BuiltinName);
}
}
- OS << "// Get the LLVM intrinsic that corresponds to a GCC builtin.\n";
- OS << "// This is used by the C front-end. The GCC builtin name is passed\n";
+ OS << "// Get the LLVM intrinsic that corresponds to a builtin.\n";
+ OS << "// This is used by the C front-end. The builtin name is passed\n";
OS << "// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed\n";
OS << "// in as TargetPrefix. The result is assigned to 'IntrinsicID'.\n";
- OS << "#ifdef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN\n";
+ OS << "#ifdef GET_LLVM_INTRINSIC_FOR_" << CompilerName << "_BUILTIN\n";
if (TargetOnly) {
OS << "static " << TargetPrefix << "Intrinsic::ID "
- << "getIntrinsicForGCCBuiltin(const char "
+ << "getIntrinsicFor" << CompilerName << "Builtin(const char "
<< "*TargetPrefixStr, const char *BuiltinNameStr) {\n";
} else {
- OS << "Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char "
+ OS << "Intrinsic::ID Intrinsic::getIntrinsicFor" << CompilerName
+ << "Builtin(const char "
<< "*TargetPrefixStr, const char *BuiltinNameStr) {\n";
}
+ OS << " static const char BuiltinNames[] = {\n";
+ Table.EmitCharArray(OS);
+ OS << " };\n\n";
+
+ OS << " struct BuiltinEntry {\n";
+ OS << " Intrinsic::ID IntrinID;\n";
+ OS << " unsigned StrTabOffset;\n";
+ OS << " const char *getName() const {\n";
+ OS << " return &BuiltinNames[StrTabOffset];\n";
+ OS << " }\n";
+ OS << " bool operator<(const char *RHS) const {\n";
+ OS << " return strcmp(getName(), RHS) < 0;\n";
+ OS << " }\n";
+ OS << " };\n";
+
OS << " StringRef BuiltinName(BuiltinNameStr);\n";
OS << " StringRef TargetPrefix(TargetPrefixStr);\n\n";
@@ -708,7 +711,18 @@ EmitIntrinsicToGCCBuiltinMap(const std::
OS << "{\n";
// Emit the comparisons for this target prefix.
- EmitTargetBuiltins(I->second, TargetPrefix, OS);
+ OS << " static const BuiltinEntry " << I->first << "Names[] = {\n";
+ for (const auto &P : I->second) {
+ OS << " {Intrinsic::" << P.second << ", "
+ << Table.GetOrAddStringOffset(P.first) << "}, // " << P.first << "\n";
+ }
+ OS << " };\n";
+ OS << " auto I = std::lower_bound(std::begin(" << I->first << "Names),\n";
+ OS << " std::end(" << I->first << "Names),\n";
+ OS << " BuiltinNameStr);\n";
+ OS << " if (I != std::end(" << I->first << "Names) &&\n";
+ OS << " strcmp(I->getName(), BuiltinNameStr) == 0)\n";
+ OS << " return I->IntrinID;\n";
OS << " }\n";
}
OS << " return ";
@@ -719,55 +733,6 @@ EmitIntrinsicToGCCBuiltinMap(const std::
OS << "#endif\n\n";
}
-void IntrinsicEmitter::
-EmitIntrinsicToMSBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
- raw_ostream &OS) {
- std::map<std::string, std::map<std::string, std::string>> TargetBuiltins;
-
- for (const auto &Intrinsic : Ints) {
- if (Intrinsic.MSBuiltinName.empty())
- continue;
-
- auto &Builtins = TargetBuiltins[Intrinsic.TargetPrefix];
- if (!Builtins.insert(std::make_pair(Intrinsic.MSBuiltinName,
- Intrinsic.EnumName)).second)
- PrintFatalError("Intrinsic '" + Intrinsic.TheDef->getName() + "': "
- "duplicate MS builtin name!");
- }
-
- OS << "// Get the LLVM intrinsic that corresponds to a MS builtin.\n"
- "// This is used by the C front-end. The MS builtin name is passed\n"
- "// in as a BuiltinName, and a target prefix (e.g. 'arm') is passed\n"
- "// in as a TargetPrefix. The result is assigned to 'IntrinsicID'.\n"
- "#ifdef GET_LLVM_INTRINSIC_FOR_MS_BUILTIN\n";
-
- OS << (TargetOnly ? "static " + TargetPrefix : "") << "Intrinsic::ID "
- << (TargetOnly ? "" : "Intrinsic::")
- << "getIntrinsicForMSBuiltin(const char *TP, const char *BN) {\n";
- OS << " StringRef BuiltinName(BN);\n"
- " StringRef TargetPrefix(TP);\n"
- "\n";
-
- for (const auto &Builtins : TargetBuiltins) {
- OS << " ";
- if (Builtins.first.empty())
- OS << "/* Target Independent Builtins */ ";
- else
- OS << "if (TargetPrefix == \"" << Builtins.first << "\") ";
- OS << "{\n";
- EmitTargetBuiltins(Builtins.second, TargetPrefix, OS);
- OS << "}";
- }
-
- OS << " return ";
- if (!TargetPrefix.empty())
- OS << "(" << TargetPrefix << "Intrinsic::ID)";
- OS << "Intrinsic::not_intrinsic;\n";
- OS << "}\n";
-
- OS << "#endif\n\n";
-}
-
void llvm::EmitIntrinsics(RecordKeeper &RK, raw_ostream &OS, bool TargetOnly) {
IntrinsicEmitter(RK, TargetOnly).run(OS);
}
More information about the llvm-commits
mailing list