summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/Function.cpp
diff options
context:
space:
mode:
authorJustin Bogner <mail@justinbogner.com>2016-07-15 16:31:37 +0000
committerJustin Bogner <mail@justinbogner.com>2016-07-15 16:31:37 +0000
commit92a8c6112c6571112e8b622bfddc7e4d1685a6fe (patch)
treeb64e83abab5974bab6c86724769cebbc6f8cf2eb /llvm/lib/IR/Function.cpp
parentf24f468e6de5119a934da72b50d39cab21c63de9 (diff)
downloadbcm5719-llvm-92a8c6112c6571112e8b622bfddc7e4d1685a6fe.tar.gz
bcm5719-llvm-92a8c6112c6571112e8b622bfddc7e4d1685a6fe.zip
IR: Sort generic intrinsics before target specific ones
This splits out the intrinsic table such that generic intrinsics come first and target specific intrinsics are grouped by target. From here we can find out which target an intrinsic is for or differentiate between generic and target intrinsics. The motivation here is to make it easier to move target specific intrinsic handling out of generic code. llvm-svn: 275575
Diffstat (limited to 'llvm/lib/IR/Function.cpp')
-rw-r--r--llvm/lib/IR/Function.cpp38
1 files changed, 33 insertions, 5 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.
OpenPOWER on IntegriCloud