forked from OSchip/llvm-project
[AST] Memoize ASTContext::getTypeInfo().
- On -emit-llvm-only of 403.gcc/combine.c, for example, we make 160k calls to getTypeInfo but only ever deal with 680 some distinct types. I saw these speedups (user time): 403.gcc/combine.c -- 3.1% OmniGroupFrameworks/NSBezierPath-OAExtensions.m -- 3.6% JavaScriptCore/Interpreter.cpp -- 1.4% which seems pretty sweet. I ran some histograms on those compiles and we end up doing a ton of getTypeInfo() on 'char' and 'int'. I tried splitting out a fast path for builtin types, but this wasn't a win. Still kinda seems like we could be doing better here. llvm-svn: 152377
This commit is contained in:
parent
564d8bc255
commit
c647587aa3
|
@ -147,6 +147,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
|||
mutable llvm::DenseMap<const ObjCContainerDecl*, const ASTRecordLayout*>
|
||||
ObjCLayouts;
|
||||
|
||||
/// TypeInfoMap - A cache from types to size and alignment information.
|
||||
typedef llvm::DenseMap<const Type*,
|
||||
std::pair<uint64_t, unsigned> > TypeInfoMap;
|
||||
mutable TypeInfoMap MemoizedTypeInfo;
|
||||
|
||||
/// KeyFunctions - A cache mapping from CXXRecordDecls to key functions.
|
||||
llvm::DenseMap<const CXXRecordDecl*, const CXXMethodDecl*> KeyFunctions;
|
||||
|
||||
|
@ -1220,6 +1225,7 @@ public:
|
|||
|
||||
private:
|
||||
CanQualType getFromTargetType(unsigned Type) const;
|
||||
std::pair<uint64_t, unsigned> getTypeInfoImpl(const Type *T) const;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Type Predicates.
|
||||
|
|
|
@ -815,14 +815,24 @@ ASTContext::getTypeInfoInChars(QualType T) const {
|
|||
return getTypeInfoInChars(T.getTypePtr());
|
||||
}
|
||||
|
||||
/// getTypeSize - Return the size of the specified type, in bits. This method
|
||||
/// does not work on incomplete types.
|
||||
std::pair<uint64_t, unsigned> ASTContext::getTypeInfo(const Type *T) const {
|
||||
TypeInfoMap::iterator it = MemoizedTypeInfo.find(T);
|
||||
if (it != MemoizedTypeInfo.end())
|
||||
return it->second;
|
||||
|
||||
std::pair<uint64_t, unsigned> Info = getTypeInfoImpl(T);
|
||||
MemoizedTypeInfo.insert(std::make_pair(T, Info));
|
||||
return Info;
|
||||
}
|
||||
|
||||
/// getTypeInfoImpl - Return the size of the specified type, in bits. This
|
||||
/// method does not work on incomplete types.
|
||||
///
|
||||
/// FIXME: Pointers into different addr spaces could have different sizes and
|
||||
/// alignment requirements: getPointerInfo should take an AddrSpace, this
|
||||
/// should take a QualType, &c.
|
||||
std::pair<uint64_t, unsigned>
|
||||
ASTContext::getTypeInfo(const Type *T) const {
|
||||
ASTContext::getTypeInfoImpl(const Type *T) const {
|
||||
uint64_t Width=0;
|
||||
unsigned Align=8;
|
||||
switch (T->getTypeClass()) {
|
||||
|
@ -851,7 +861,8 @@ ASTContext::getTypeInfo(const Type *T) const {
|
|||
|
||||
std::pair<uint64_t, unsigned> EltInfo = getTypeInfo(CAT->getElementType());
|
||||
uint64_t Size = CAT->getSize().getZExtValue();
|
||||
assert((Size == 0 || EltInfo.first <= (uint64_t)(-1)/Size) && "Overflow in array type bit size evaluation");
|
||||
assert((Size == 0 || EltInfo.first <= (uint64_t)(-1)/Size) &&
|
||||
"Overflow in array type bit size evaluation");
|
||||
Width = EltInfo.first*Size;
|
||||
Align = EltInfo.second;
|
||||
Width = llvm::RoundUpToAlignment(Width, Align);
|
||||
|
|
Loading…
Reference in New Issue