diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/IR/Function.cpp | 38 | ||||
-rw-r--r-- | llvm/utils/TableGen/CodeGenDAGPatterns.cpp | 4 | ||||
-rw-r--r-- | llvm/utils/TableGen/CodeGenDAGPatterns.h | 4 | ||||
-rw-r--r-- | llvm/utils/TableGen/CodeGenIntrinsics.h | 24 | ||||
-rw-r--r-- | llvm/utils/TableGen/CodeGenTarget.cpp | 24 | ||||
-rw-r--r-- | llvm/utils/TableGen/IntrinsicEmitter.cpp | 61 |
6 files changed, 111 insertions, 44 deletions
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index 42fb7649aa6..e1223d0d033 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -461,17 +461,45 @@ static const char * const IntrinsicNameTable[] = { #undef GET_INTRINSIC_NAME_TABLE }; +/// Table of per-target intrinsic name tables. +#define GET_INTRINSIC_TARGET_DATA +#include "llvm/IR/Intrinsics.gen" +#undef GET_INTRINSIC_TARGET_DATA + +/// Find the segment of \c IntrinsicNameTable for intrinsics with the same +/// target as \c Name, or the generic table if \c Name is not target specific. +/// +/// Returns the relevant slice of \c IntrinsicNameTable +static ArrayRef<const char *> findTargetSubtable(StringRef Name) { + assert(Name.startswith("llvm.")); + + ArrayRef<IntrinsicTargetInfo> Targets(TargetInfos); + // Drop "llvm." and take the first dotted component. That will be the target + // if this is target specific. + StringRef Target = Name.drop_front(5).split('.').first; + auto It = std::lower_bound(Targets.begin(), Targets.end(), Target, + [](const IntrinsicTargetInfo &TI, + StringRef Target) { return TI.Name < Target; }); + // We've either found the target or just fall back to the generic set, which + // is always first. + const auto &TI = It != Targets.end() && It->Name == Target ? *It : Targets[0]; + return makeArrayRef(&IntrinsicNameTable[1] + TI.Offset, TI.Count); +} + /// \brief This does the actual lookup of an intrinsic ID which /// matches the given function name. static Intrinsic::ID lookupIntrinsicID(const ValueName *ValName) { StringRef Name = ValName->getKey(); - ArrayRef<const char *> NameTable(&IntrinsicNameTable[1], - std::end(IntrinsicNameTable)); + ArrayRef<const char *> NameTable = findTargetSubtable(Name); int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable, Name); - Intrinsic::ID ID = static_cast<Intrinsic::ID>(Idx + 1); - if (ID == Intrinsic::not_intrinsic) - return ID; + if (Idx == -1) + return Intrinsic::not_intrinsic; + + // Intrinsic IDs correspond to the location in IntrinsicNameTable, but we have + // an index into a sub-table. + int Adjust = NameTable.data() - IntrinsicNameTable; + Intrinsic::ID ID = static_cast<Intrinsic::ID>(Idx + Adjust); // If the intrinsic is not overloaded, require an exact match. If it is // overloaded, require a prefix match. diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp index c2bb55f3dd4..307a95373c9 100644 --- a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp @@ -2392,8 +2392,8 @@ void TreePattern::dump() const { print(errs()); } CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) : Records(R), Target(R) { - Intrinsics = LoadIntrinsics(Records, false); - TgtIntrinsics = LoadIntrinsics(Records, true); + Intrinsics = CodeGenIntrinsicTable(Records, false); + TgtIntrinsics = CodeGenIntrinsicTable(Records, true); ParseNodeInfo(); ParseNodeTransforms(); ParseComplexPatterns(); diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.h b/llvm/utils/TableGen/CodeGenDAGPatterns.h index 76c9cefea50..819c4b8492c 100644 --- a/llvm/utils/TableGen/CodeGenDAGPatterns.h +++ b/llvm/utils/TableGen/CodeGenDAGPatterns.h @@ -716,8 +716,8 @@ public: class CodeGenDAGPatterns { RecordKeeper &Records; CodeGenTarget Target; - std::vector<CodeGenIntrinsic> Intrinsics; - std::vector<CodeGenIntrinsic> TgtIntrinsics; + CodeGenIntrinsicTable Intrinsics; + CodeGenIntrinsicTable TgtIntrinsics; std::map<Record*, SDNodeInfo, LessRecordByID> SDNodes; std::map<Record*, std::pair<Record*, std::string>, LessRecordByID> SDNodeXForms; diff --git a/llvm/utils/TableGen/CodeGenIntrinsics.h b/llvm/utils/TableGen/CodeGenIntrinsics.h index 76554a52a15..ea3ec67d62e 100644 --- a/llvm/utils/TableGen/CodeGenIntrinsics.h +++ b/llvm/utils/TableGen/CodeGenIntrinsics.h @@ -114,9 +114,27 @@ struct CodeGenIntrinsic { CodeGenIntrinsic(Record *R); }; -/// Read all of the intrinsics defined in the specified .td file. -std::vector<CodeGenIntrinsic> LoadIntrinsics(const RecordKeeper &RC, - bool TargetOnly); +class CodeGenIntrinsicTable { + std::vector<CodeGenIntrinsic> Intrinsics; + +public: + struct TargetSet { + std::string Name; + size_t Offset; + size_t Count; + }; + std::vector<TargetSet> Targets; + + explicit CodeGenIntrinsicTable(const RecordKeeper &RC, bool TargetOnly); + CodeGenIntrinsicTable() = default; + + bool empty() const { return Intrinsics.empty(); } + size_t size() const { return Intrinsics.size(); } + CodeGenIntrinsic &operator[](size_t Pos) { return Intrinsics[Pos]; } + const CodeGenIntrinsic &operator[](size_t Pos) const { + return Intrinsics[Pos]; + } +}; } #endif diff --git a/llvm/utils/TableGen/CodeGenTarget.cpp b/llvm/utils/TableGen/CodeGenTarget.cpp index 08bb332b135..245b9eeeed8 100644 --- a/llvm/utils/TableGen/CodeGenTarget.cpp +++ b/llvm/utils/TableGen/CodeGenTarget.cpp @@ -426,23 +426,29 @@ ComplexPattern::ComplexPattern(Record *R) { // CodeGenIntrinsic Implementation //===----------------------------------------------------------------------===// -std::vector<CodeGenIntrinsic> llvm::LoadIntrinsics(const RecordKeeper &RC, - bool TargetOnly) { +CodeGenIntrinsicTable::CodeGenIntrinsicTable(const RecordKeeper &RC, + bool TargetOnly) { std::vector<Record*> Defs = RC.getAllDerivedDefinitions("Intrinsic"); - std::vector<CodeGenIntrinsic> Result; - Result.reserve(Defs.size()); + Intrinsics.reserve(Defs.size()); for (unsigned I = 0, e = Defs.size(); I != e; ++I) { bool isTarget = Defs[I]->getValueAsBit("isTarget"); if (isTarget == TargetOnly) - Result.push_back(CodeGenIntrinsic(Defs[I])); + Intrinsics.push_back(CodeGenIntrinsic(Defs[I])); } - std::sort(Result.begin(), Result.end(), - [](const CodeGenIntrinsic& LHS, const CodeGenIntrinsic& RHS) { - return LHS.Name < RHS.Name; + std::sort(Intrinsics.begin(), Intrinsics.end(), + [](const CodeGenIntrinsic &LHS, const CodeGenIntrinsic &RHS) { + return std::tie(LHS.TargetPrefix, LHS.Name) < + std::tie(RHS.TargetPrefix, RHS.Name); }); - return Result; + Targets.push_back({"", 0, 0}); + for (size_t I = 0, E = Intrinsics.size(); I < E; ++I) + if (Intrinsics[I].TargetPrefix != Targets.back().Name) { + Targets.back().Count = I - Targets.back().Offset; + Targets.push_back({Intrinsics[I].TargetPrefix, I, 0}); + } + Targets.back().Count = Intrinsics.size() - Targets.back().Offset; } CodeGenIntrinsic::CodeGenIntrinsic(Record *R) { diff --git a/llvm/utils/TableGen/IntrinsicEmitter.cpp b/llvm/utils/TableGen/IntrinsicEmitter.cpp index 062d25c6a4e..a676159e494 100644 --- a/llvm/utils/TableGen/IntrinsicEmitter.cpp +++ b/llvm/utils/TableGen/IntrinsicEmitter.cpp @@ -38,19 +38,16 @@ public: void EmitPrefix(raw_ostream &OS); - void EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints, - raw_ostream &OS); - - void EmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints, + void EmitEnumInfo(const CodeGenIntrinsicTable &Ints, raw_ostream &OS); + void EmitTargetInfo(const CodeGenIntrinsicTable &Ints, raw_ostream &OS); + void EmitIntrinsicToNameTable(const CodeGenIntrinsicTable &Ints, raw_ostream &OS); - void EmitIntrinsicToOverloadTable(const std::vector<CodeGenIntrinsic> &Ints, + void EmitIntrinsicToOverloadTable(const CodeGenIntrinsicTable &Ints, raw_ostream &OS); - void EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, - raw_ostream &OS); - void EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, - raw_ostream &OS); - void EmitIntrinsicToBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, - bool IsGCC, raw_ostream &OS); + void EmitGenerator(const CodeGenIntrinsicTable &Ints, raw_ostream &OS); + void EmitAttributes(const CodeGenIntrinsicTable &Ints, raw_ostream &OS); + void EmitIntrinsicToBuiltinMap(const CodeGenIntrinsicTable &Ints, bool IsGCC, + raw_ostream &OS); void EmitSuffix(raw_ostream &OS); }; } // End anonymous namespace @@ -62,7 +59,7 @@ public: void IntrinsicEmitter::run(raw_ostream &OS) { emitSourceFileHeader("Intrinsic Function Source Fragment", OS); - std::vector<CodeGenIntrinsic> Ints = LoadIntrinsics(Records, TargetOnly); + CodeGenIntrinsicTable Ints(Records, TargetOnly); if (TargetOnly && !Ints.empty()) TargetPrefix = Ints[0].TargetPrefix; @@ -72,6 +69,9 @@ void IntrinsicEmitter::run(raw_ostream &OS) { // Emit the enum information. EmitEnumInfo(Ints, OS); + // Emit the target metadata. + EmitTargetInfo(Ints, OS); + // Emit the intrinsic ID -> name table. EmitIntrinsicToNameTable(Ints, OS); @@ -114,7 +114,7 @@ void IntrinsicEmitter::EmitSuffix(raw_ostream &OS) { "#endif\n\n"; } -void IntrinsicEmitter::EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints, +void IntrinsicEmitter::EmitEnumInfo(const CodeGenIntrinsicTable &Ints, raw_ostream &OS) { OS << "// Enum values for Intrinsics.h\n"; OS << "#ifdef GET_INTRINSIC_ENUM_VALUES\n"; @@ -128,9 +128,25 @@ void IntrinsicEmitter::EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints, OS << "#endif\n\n"; } -void IntrinsicEmitter:: -EmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints, - raw_ostream &OS) { +void IntrinsicEmitter::EmitTargetInfo(const CodeGenIntrinsicTable &Ints, + raw_ostream &OS) { + OS << "// Target mapping\n"; + OS << "#ifdef GET_INTRINSIC_TARGET_DATA\n"; + OS << "struct IntrinsicTargetInfo {\n" + << " StringRef Name;\n" + << " size_t Offset;\n" + << " size_t Count;\n" + << "};\n"; + OS << "static const IntrinsicTargetInfo TargetInfos[] = {\n"; + for (auto Target : Ints.Targets) + OS << " {\"" << Target.Name << "\", " << Target.Offset << ", " + << Target.Count << "},\n"; + OS << "};\n"; + OS << "#endif\n\n"; +} + +void IntrinsicEmitter::EmitIntrinsicToNameTable( + const CodeGenIntrinsicTable &Ints, raw_ostream &OS) { OS << "// Intrinsic ID to name table\n"; OS << "#ifdef GET_INTRINSIC_NAME_TABLE\n"; OS << " // Note that entry #0 is the invalid intrinsic!\n"; @@ -139,9 +155,8 @@ EmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints, OS << "#endif\n\n"; } -void IntrinsicEmitter:: -EmitIntrinsicToOverloadTable(const std::vector<CodeGenIntrinsic> &Ints, - raw_ostream &OS) { +void IntrinsicEmitter::EmitIntrinsicToOverloadTable( + const CodeGenIntrinsicTable &Ints, raw_ostream &OS) { OS << "// Intrinsic ID to overload bitset\n"; OS << "#ifdef GET_INTRINSIC_OVERLOAD_TABLE\n"; OS << "static const uint8_t OTable[] = {\n"; @@ -363,7 +378,7 @@ static void printIITEntry(raw_ostream &OS, unsigned char X) { OS << (unsigned)X; } -void IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, +void IntrinsicEmitter::EmitGenerator(const CodeGenIntrinsicTable &Ints, raw_ostream &OS) { // If we can compute a 32-bit fixed encoding for this intrinsic, do so and // capture it in this vector, otherwise store a ~0U. @@ -474,8 +489,8 @@ struct AttributeComparator { } // End anonymous namespace /// EmitAttributes - This emits the Intrinsic::getAttributes method. -void IntrinsicEmitter:: -EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { +void IntrinsicEmitter::EmitAttributes(const CodeGenIntrinsicTable &Ints, + raw_ostream &OS) { OS << "// Add parameter attributes that are not common to all intrinsics.\n"; OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n"; if (TargetOnly) @@ -670,7 +685,7 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { } void IntrinsicEmitter::EmitIntrinsicToBuiltinMap( - const std::vector<CodeGenIntrinsic> &Ints, bool IsGCC, raw_ostream &OS) { + const CodeGenIntrinsicTable &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; |