diff options
author | Michael Ilseman <milseman@apple.com> | 2013-03-01 18:48:54 +0000 |
---|---|---|
committer | Michael Ilseman <milseman@apple.com> | 2013-03-01 18:48:54 +0000 |
commit | 4c8e74f0b75cb10820c45c86399fbd02e4a8832a (patch) | |
tree | cc1f1cdb45bee8daff09970eaa0d992d952b6edf /lib/IR | |
parent | a6b20ced765b67a85d9219d0c8547fc9c133e14f (diff) | |
download | external_llvm-4c8e74f0b75cb10820c45c86399fbd02e4a8832a.zip external_llvm-4c8e74f0b75cb10820c45c86399fbd02e4a8832a.tar.gz external_llvm-4c8e74f0b75cb10820c45c86399fbd02e4a8832a.tar.bz2 |
Cache the result of Function::getIntrinsicID() in a DenseMap attached to the LLVMContext.
This reduces the time actually spent doing string to ID conversion and shows a 10% improvement in compile time for a particularly bad case that involves ARM Neon intrinsics (these have many overloads).
Patch by Jean-Luc Duprat!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@176365 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/IR')
-rw-r--r-- | lib/IR/Function.cpp | 24 | ||||
-rw-r--r-- | lib/IR/LLVMContextImpl.h | 7 | ||||
-rw-r--r-- | lib/IR/Module.cpp | 1 | ||||
-rw-r--r-- | lib/IR/Value.cpp | 9 |
4 files changed, 36 insertions, 5 deletions
diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp index 5c444d2..5559a6c 100644 --- a/lib/IR/Function.cpp +++ b/lib/IR/Function.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/IR/Function.h" +#include "LLVMContextImpl.h" #include "SymbolTableListTraitsImpl.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" @@ -208,6 +209,10 @@ Function::~Function() { // Remove the function from the on-the-side GC table. clearGC(); + + // Remove the intrinsicID from the Cache. + if(getValueName() && isIntrinsic()) + getContext().pImpl->IntrinsicIDCache.erase(this); } void Function::BuildLazyArguments() const { @@ -337,18 +342,35 @@ void Function::copyAttributesFrom(const GlobalValue *Src) { /// intrinsic, or if the pointer is null. This value is always defined to be /// zero to allow easy checking for whether a function is intrinsic or not. The /// particular intrinsic functions which correspond to this value are defined in -/// llvm/Intrinsics.h. +/// llvm/Intrinsics.h. Results are cached in the LLVM context, subsequent +/// requests for the same ID return results much faster from the cache. /// unsigned Function::getIntrinsicID() const { const ValueName *ValName = this->getValueName(); if (!ValName || !isIntrinsic()) return 0; + + LLVMContextImpl::IntrinsicIDCacheTy &IntrinsicIDCache = + getContext().pImpl->IntrinsicIDCache; + if(!IntrinsicIDCache.count(this)) { + unsigned Id = lookupIntrinsicID(); + IntrinsicIDCache[this]=Id; + return Id; + } + return IntrinsicIDCache[this]; +} + +/// This private method does the actual lookup of an intrinsic ID when the query +/// could not be answered from the cache. +unsigned Function::lookupIntrinsicID() const { + const ValueName *ValName = this->getValueName(); unsigned Len = ValName->getKeyLength(); const char *Name = ValName->getKeyData(); #define GET_FUNCTION_RECOGNIZER #include "llvm/IR/Intrinsics.gen" #undef GET_FUNCTION_RECOGNIZER + return 0; } diff --git a/lib/IR/LLVMContextImpl.h b/lib/IR/LLVMContextImpl.h index 7353dc0..0c659b8 100644 --- a/lib/IR/LLVMContextImpl.h +++ b/lib/IR/LLVMContextImpl.h @@ -318,7 +318,7 @@ public: /// ValueHandles - This map keeps track of all of the value handles that are /// watching a Value*. The Value::HasValueHandle bit is used to know - // whether or not a value has an entry in this map. + /// whether or not a value has an entry in this map. typedef DenseMap<Value*, ValueHandleBase*> ValueHandlesTy; ValueHandlesTy ValueHandles; @@ -350,6 +350,11 @@ public: /// to date. std::vector<std::pair<DebugRecVH, DebugRecVH> > ScopeInlinedAtRecords; + /// IntrinsicIDCache - Cache of intrinsic name (string) to numeric ID mappings + /// requested in this context + typedef DenseMap<const Function*, unsigned> IntrinsicIDCacheTy; + IntrinsicIDCacheTy IntrinsicIDCache; + int getOrAddScopeRecordIdxEntry(MDNode *N, int ExistingIdx); int getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA,int ExistingIdx); diff --git a/lib/IR/Module.cpp b/lib/IR/Module.cpp index 8affcc9..0825bda 100644 --- a/lib/IR/Module.cpp +++ b/lib/IR/Module.cpp @@ -13,6 +13,7 @@ #include "llvm/IR/Module.h" #include "SymbolTableListTraitsImpl.h" +#include "LLVMContextImpl.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" diff --git a/lib/IR/Value.cpp b/lib/IR/Value.cpp index 5bdce2b..adc702e 100644 --- a/lib/IR/Value.cpp +++ b/lib/IR/Value.cpp @@ -195,6 +195,9 @@ void Value::setName(const Twine &NewName) { if (getSymTab(this, ST)) return; // Cannot set a name on this value (e.g. constant). + if (Function *F = dyn_cast<Function>(this)) + getContext().pImpl->IntrinsicIDCache.erase(F); + if (!ST) { // No symbol table to update? Just do the change. if (NameRef.empty()) { // Free the name for this value. @@ -307,7 +310,7 @@ void Value::replaceAllUsesWith(Value *New) { // Notify all ValueHandles (if present) that this value is going away. if (HasValueHandle) ValueHandleBase::ValueIsRAUWd(this, New); - + while (!use_empty()) { Use &U = *UseList; // Must handle Constants specially, we cannot call replaceUsesOfWith on a @@ -318,10 +321,10 @@ void Value::replaceAllUsesWith(Value *New) { continue; } } - + U.set(New); } - + if (BasicBlock *BB = dyn_cast<BasicBlock>(this)) BB->replaceSuccessorsPhiUsesWith(cast<BasicBlock>(New)); } |