summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/IntrinsicInst.cpp
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2016-01-26 22:33:19 +0000
committerReid Kleckner <rnk@google.com>2016-01-26 22:33:19 +0000
commitc2752daa6bf70786ebbb448208af8fb62a431ecc (patch)
tree30f5d3485a097097f1b05b97a178e64753b9a89d /llvm/lib/IR/IntrinsicInst.cpp
parent7da47b8ef5efc16caef8cbd45f495baf9b383370 (diff)
downloadbcm5719-llvm-c2752daa6bf70786ebbb448208af8fb62a431ecc.tar.gz
bcm5719-llvm-c2752daa6bf70786ebbb448208af8fb62a431ecc.zip
Handle more edge cases in intrinsic name binary search
I tried to make the AMDGPU intrinsic info table use this instead of another StringMatcher, and some issues arose. llvm-svn: 258871
Diffstat (limited to 'llvm/lib/IR/IntrinsicInst.cpp')
-rw-r--r--llvm/lib/IR/IntrinsicInst.cpp39
1 files changed, 39 insertions, 0 deletions
diff --git a/llvm/lib/IR/IntrinsicInst.cpp b/llvm/lib/IR/IntrinsicInst.cpp
index b9b5a29091d..427cfef5fa3 100644
--- a/llvm/lib/IR/IntrinsicInst.cpp
+++ b/llvm/lib/IR/IntrinsicInst.cpp
@@ -25,6 +25,7 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Metadata.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
@@ -79,3 +80,41 @@ const Value *DbgValueInst::getValue() const {
}
Value *DbgValueInst::getValue() { return getValueImpl(getArgOperand(0)); }
+
+int llvm::Intrinsic::lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
+ StringRef Name) {
+ assert(Name.startswith("llvm."));
+
+ // Do successive binary searches of the dotted name components. For
+ // "llvm.gc.experimental.statepoint.p1i8.p1i32", we will find the range of
+ // intrinsics starting with "llvm.gc", then "llvm.gc.experimental", then
+ // "llvm.gc.experimental.statepoint", and then we will stop as the range is
+ // size 1. During the search, we can skip the prefix that we already know is
+ // identical. By using strncmp we consider names with differing suffixes to
+ // be part of the equal range.
+ size_t CmpStart = 0;
+ size_t CmpEnd = 4; // Skip the "llvm" component.
+ const char *const *Low = NameTable.begin();
+ const char *const *High = NameTable.end();
+ const char *const *LastLow = Low;
+ while (CmpEnd < Name.size() && High - Low > 0) {
+ CmpStart = CmpEnd;
+ CmpEnd = Name.find('.', CmpStart + 1);
+ CmpEnd = CmpEnd == StringRef::npos ? Name.size() : CmpEnd;
+ auto Cmp = [CmpStart, CmpEnd](const char *LHS, const char *RHS) {
+ return strncmp(LHS + CmpStart, RHS + CmpStart, CmpEnd - CmpStart) < 0;
+ };
+ LastLow = Low;
+ std::tie(Low, High) = std::equal_range(Low, High, Name.data(), Cmp);
+ }
+ if (High - Low > 0)
+ LastLow = Low;
+
+ if (LastLow == NameTable.end())
+ return -1;
+ StringRef NameFound = *LastLow;
+ if (Name == NameFound ||
+ (Name.startswith(NameFound) && Name[NameFound.size()] == '.'))
+ return LastLow - NameTable.begin();
+ return -1;
+}
OpenPOWER on IntegriCloud