mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 15:11:24 +00:00
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
This commit is contained in:
parent
a6b20ced76
commit
4c8e74f0b7
@ -113,6 +113,10 @@ private:
|
|||||||
Function(const Function&) LLVM_DELETED_FUNCTION;
|
Function(const Function&) LLVM_DELETED_FUNCTION;
|
||||||
void operator=(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 ctor - If the (optional) Module argument is specified, the
|
||||||
/// function is automatically inserted into the end of the function list for
|
/// function is automatically inserted into the end of the function list for
|
||||||
/// the module.
|
/// the module.
|
||||||
@ -141,10 +145,12 @@ public:
|
|||||||
|
|
||||||
/// getIntrinsicID - This method returns the ID number of the specified
|
/// getIntrinsicID - This method returns the ID number of the specified
|
||||||
/// function, or Intrinsic::not_intrinsic if the function is not an
|
/// 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.
|
/// zero to allow easy checking for whether a function is intrinsic or not.
|
||||||
/// The particular intrinsic functions which correspond to this value are
|
/// 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;
|
unsigned getIntrinsicID() const LLVM_READONLY;
|
||||||
bool isIntrinsic() const { return getName().startswith("llvm."); }
|
bool isIntrinsic() const { return getName().startswith("llvm."); }
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/IR/Function.h"
|
#include "llvm/IR/Function.h"
|
||||||
|
#include "LLVMContextImpl.h"
|
||||||
#include "SymbolTableListTraitsImpl.h"
|
#include "SymbolTableListTraitsImpl.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
@ -208,6 +209,10 @@ Function::~Function() {
|
|||||||
|
|
||||||
// Remove the function from the on-the-side GC table.
|
// Remove the function from the on-the-side GC table.
|
||||||
clearGC();
|
clearGC();
|
||||||
|
|
||||||
|
// Remove the intrinsicID from the Cache.
|
||||||
|
if(getValueName() && isIntrinsic())
|
||||||
|
getContext().pImpl->IntrinsicIDCache.erase(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Function::BuildLazyArguments() const {
|
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
|
/// 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
|
/// 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
|
/// 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 {
|
unsigned Function::getIntrinsicID() const {
|
||||||
const ValueName *ValName = this->getValueName();
|
const ValueName *ValName = this->getValueName();
|
||||||
if (!ValName || !isIntrinsic())
|
if (!ValName || !isIntrinsic())
|
||||||
return 0;
|
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();
|
unsigned Len = ValName->getKeyLength();
|
||||||
const char *Name = ValName->getKeyData();
|
const char *Name = ValName->getKeyData();
|
||||||
|
|
||||||
#define GET_FUNCTION_RECOGNIZER
|
#define GET_FUNCTION_RECOGNIZER
|
||||||
#include "llvm/IR/Intrinsics.gen"
|
#include "llvm/IR/Intrinsics.gen"
|
||||||
#undef GET_FUNCTION_RECOGNIZER
|
#undef GET_FUNCTION_RECOGNIZER
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,7 +318,7 @@ public:
|
|||||||
|
|
||||||
/// ValueHandles - This map keeps track of all of the value handles that are
|
/// ValueHandles - This map keeps track of all of the value handles that are
|
||||||
/// watching a Value*. The Value::HasValueHandle bit is used to know
|
/// 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;
|
typedef DenseMap<Value*, ValueHandleBase*> ValueHandlesTy;
|
||||||
ValueHandlesTy ValueHandles;
|
ValueHandlesTy ValueHandles;
|
||||||
|
|
||||||
@ -350,6 +350,11 @@ public:
|
|||||||
/// to date.
|
/// to date.
|
||||||
std::vector<std::pair<DebugRecVH, DebugRecVH> > ScopeInlinedAtRecords;
|
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 getOrAddScopeRecordIdxEntry(MDNode *N, int ExistingIdx);
|
||||||
int getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA,int ExistingIdx);
|
int getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA,int ExistingIdx);
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
#include "SymbolTableListTraitsImpl.h"
|
#include "SymbolTableListTraitsImpl.h"
|
||||||
|
#include "LLVMContextImpl.h"
|
||||||
#include "llvm/ADT/DenseSet.h"
|
#include "llvm/ADT/DenseSet.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
#include "llvm/ADT/SmallString.h"
|
#include "llvm/ADT/SmallString.h"
|
||||||
|
@ -195,6 +195,9 @@ void Value::setName(const Twine &NewName) {
|
|||||||
if (getSymTab(this, ST))
|
if (getSymTab(this, ST))
|
||||||
return; // Cannot set a name on this value (e.g. constant).
|
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 (!ST) { // No symbol table to update? Just do the change.
|
||||||
if (NameRef.empty()) {
|
if (NameRef.empty()) {
|
||||||
// Free the name for this value.
|
// 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.
|
// Notify all ValueHandles (if present) that this value is going away.
|
||||||
if (HasValueHandle)
|
if (HasValueHandle)
|
||||||
ValueHandleBase::ValueIsRAUWd(this, New);
|
ValueHandleBase::ValueIsRAUWd(this, New);
|
||||||
|
|
||||||
while (!use_empty()) {
|
while (!use_empty()) {
|
||||||
Use &U = *UseList;
|
Use &U = *UseList;
|
||||||
// Must handle Constants specially, we cannot call replaceUsesOfWith on a
|
// Must handle Constants specially, we cannot call replaceUsesOfWith on a
|
||||||
@ -318,10 +321,10 @@ void Value::replaceAllUsesWith(Value *New) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
U.set(New);
|
U.set(New);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BasicBlock *BB = dyn_cast<BasicBlock>(this))
|
if (BasicBlock *BB = dyn_cast<BasicBlock>(this))
|
||||||
BB->replaceSuccessorsPhiUsesWith(cast<BasicBlock>(New));
|
BB->replaceSuccessorsPhiUsesWith(cast<BasicBlock>(New));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user