summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorJustin Lebar <jlebar@google.com>2016-07-27 23:46:57 +0000
committerJustin Lebar <jlebar@google.com>2016-07-27 23:46:57 +0000
commit45bcdcbefbfda867965fec755391f6ad0925f74a (patch)
tree8037c44903747af63d7a16a777685dd8dafbcd6d /llvm
parentff5ce639deb23595b4c4c9b995d6d6d47dda64fb (diff)
downloadbcm5719-llvm-45bcdcbefbfda867965fec755391f6ad0925f74a.tar.gz
bcm5719-llvm-45bcdcbefbfda867965fec755391f6ad0925f74a.zip
Don't invoke getName() from Function::isIntrinsic().
Summary: getName() involves a hashtable lookup, so is expensive given how frequently isIntrinsic() is called. (In particular, many users cast to IntrinsicInstr or one of its subclasses before calling getIntrinsicID().) This has an incidental functional change: Before, isIntrinsic() would return true for any function whose name started with "llvm.", even if it wasn't properly an intrinsic. The new behavior seems more correct to me, because it's strange to say that isIntrinsic() is true, but getIntrinsicId() returns "not an intrinsic". Some callers want the old behavior -- they want to know whether the caller is a recognized intrinsic, or might be one in some other version of LLVM. For them, we added Function::hasLLVMReservedName(), which checks whether the name starts with "llvm.". This change is good for a 1.5% e2e speedup compiling a large Eigen benchmark. Reviewers: bogner Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D22065 llvm-svn: 276942
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/IR/Function.h8
-rw-r--r--llvm/lib/CodeGen/WinEHPrepare.cpp8
-rw-r--r--llvm/lib/IR/AsmWriter.cpp4
-rw-r--r--llvm/lib/IR/Function.cpp9
-rw-r--r--llvm/lib/IR/Verifier.cpp2
5 files changed, 19 insertions, 12 deletions
diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h
index 2b4ce6d7a1b..7fe58cf7ff5 100644
--- a/llvm/include/llvm/IR/Function.h
+++ b/llvm/include/llvm/IR/Function.h
@@ -137,7 +137,13 @@ public:
/// The particular intrinsic functions which correspond to this value are
/// defined in llvm/Intrinsics.h.
Intrinsic::ID getIntrinsicID() const LLVM_READONLY { return IntID; }
- bool isIntrinsic() const { return getName().startswith("llvm."); }
+ bool isIntrinsic() const {
+ // Intrinsic::not_intrinsic must be 0.
+ return IntID != 0;
+ }
+ /// Return true if the function's name starts with "llvm.". All intrinsics
+ /// have this prefix.
+ bool hasLLVMReservedName() const { return getName().startswith("llvm."); }
/// \brief Recalculate the ID for this function if it is an Intrinsic defined
/// in llvm/Intrinsics.h. Sets the intrinsic ID to Intrinsic::not_intrinsic
diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp
index 041fb7b912b..28efee08581 100644
--- a/llvm/lib/CodeGen/WinEHPrepare.cpp
+++ b/llvm/lib/CodeGen/WinEHPrepare.cpp
@@ -949,10 +949,14 @@ void WinEHPrepare::removeImplausibleInstructions(Function &F) {
continue;
// Skip call sites which are nounwind intrinsics or inline asm.
+ //
+ // FIXME: Should this check isIntrinsic() instead of
+ // hasLLVMReservedName? The latter is conservative.
auto *CalledFn =
dyn_cast<Function>(CS.getCalledValue()->stripPointerCasts());
- if (CalledFn && ((CalledFn->isIntrinsic() && CS.doesNotThrow()) ||
- CS.isInlineAsm()))
+ if (CalledFn &&
+ ((CalledFn->hasLLVMReservedName() && CS.doesNotThrow()) ||
+ CS.isInlineAsm()))
continue;
// This call site was not part of this funclet, remove it.
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 9b2399dd880..bf5cc187e86 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -905,7 +905,7 @@ void SlotTracker::processInstructionMetadata(const Instruction &I) {
// Process metadata used directly by intrinsics.
if (const CallInst *CI = dyn_cast<CallInst>(&I))
if (Function *F = CI->getCalledFunction())
- if (F->isIntrinsic())
+ if (F->hasLLVMReservedName())
for (auto &Op : I.operands())
if (auto *V = dyn_cast_or_null<MetadataAsValue>(Op))
if (MDNode *N = dyn_cast<MDNode>(V->getMetadata()))
@@ -3378,7 +3378,7 @@ void Type::print(raw_ostream &OS, bool /*IsForDebug*/, bool NoDetails) const {
static bool isReferencingMDNode(const Instruction &I) {
if (const auto *CI = dyn_cast<CallInst>(&I))
if (Function *F = CI->getCalledFunction())
- if (F->isIntrinsic())
+ if (F->hasLLVMReservedName())
for (auto &Op : I.operands())
if (auto *V = dyn_cast_or_null<MetadataAsValue>(Op))
if (isa<MDNode>(V->getMetadata()))
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index e1223d0d033..d9c59241ddf 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -488,9 +488,7 @@ static ArrayRef<const char *> findTargetSubtable(StringRef Name) {
/// \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();
-
+static Intrinsic::ID lookupIntrinsicID(StringRef Name) {
ArrayRef<const char *> NameTable = findTargetSubtable(Name);
int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable, Name);
if (Idx == -1)
@@ -508,12 +506,11 @@ static Intrinsic::ID lookupIntrinsicID(const ValueName *ValName) {
}
void Function::recalculateIntrinsicID() {
- const ValueName *ValName = this->getValueName();
- if (!ValName || !isIntrinsic()) {
+ if (!hasLLVMReservedName()) {
IntID = Intrinsic::not_intrinsic;
return;
}
- IntID = lookupIntrinsicID(ValName);
+ IntID = lookupIntrinsicID(getName());
}
/// Returns a stable mangling for the type specified for use in the name
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 682e934d4b0..659a22428e2 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -3647,7 +3647,7 @@ void Verifier::visitInstruction(Instruction &I) {
// Check to make sure that the "address of" an intrinsic function is never
// taken.
Assert(
- !F->isIntrinsic() ||
+ !F->hasLLVMReservedName() ||
i == (isa<CallInst>(I) ? e - 1 : isa<InvokeInst>(I) ? e - 3 : 0),
"Cannot take the address of an intrinsic!", &I);
Assert(
OpenPOWER on IntegriCloud