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!
llvm-svn: 176365
Function(const Function&) LLVM_DELETED_FUNCTION;
void operator=(const Function&) LLVM_DELETED_FUNCTION;
+ /// Do the actual lookup of an intrinsic ID when the query could not be
+ /// answered from the cache.
+ unsigned lookupIntrinsicID() const LLVM_READONLY;
+
/// Function ctor - If the (optional) Module argument is specified, the
/// function is automatically inserted into the end of the function list for
/// the module.
/// getIntrinsicID - This method returns the ID number of the specified
/// function, or Intrinsic::not_intrinsic if the function is not an
- /// instrinsic, or if the pointer is null. This value is always defined to be
+ /// 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.
+ /// defined in llvm/Intrinsics.h. Results are cached in the LLVM context,
+ /// subsequent requests for the same ID return results much faster from the
+ /// cache.
///
unsigned getIntrinsicID() const LLVM_READONLY;
bool isIntrinsic() const { return getName().startswith("llvm."); }
//===----------------------------------------------------------------------===//
#include "llvm/IR/Function.h"
+#include "LLVMContextImpl.h"
#include "SymbolTableListTraitsImpl.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
// 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 {
/// 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;
}
/// 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;
/// 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);
#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"
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.
// 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
continue;
}
}
-
+
U.set(New);
}
-
+
if (BasicBlock *BB = dyn_cast<BasicBlock>(this))
BB->replaceSuccessorsPhiUsesWith(cast<BasicBlock>(New));
}