Switch arraytypes over to using a FoldingSet instead of a stupid linear

search.  This reduces 'dumb' lookups from 1225 to 359, speeding up parse
of carbon.h from 0.173 to 0.156s (10%).

llvm-svn: 39319
This commit is contained in:
Chris Lattner 2007-01-27 08:31:04 +00:00
parent 25fe86af2b
commit 36f8e65eef
4 changed files with 34 additions and 15 deletions

View File

@ -164,26 +164,31 @@ TypeRef ASTContext::getArrayType(TypeRef EltTy,ArrayType::ArraySizeModifier ASM,
unsigned EltTypeQuals, void *NumElts) {
#warning "IGNORING SIZE"
// FIXME: This is obviously braindead!
// Unique array, to guarantee there is only one array of a particular
// Unique array types, to guarantee there is only one array of a particular
// structure.
++NumSlowLookups;
for (unsigned i = 0, e = Types.size(); i != e; ++i)
if (ArrayType *ATy = dyn_cast<ArrayType>(Types[i]))
if (ATy->getElementType() == EltTy &&
ATy->getSizeModifier() == ASM &&
ATy->getIndexTypeQualifier() == EltTypeQuals)
return Types[i];
FoldingSetNodeID ID;
ArrayType::Profile(ID, ASM, EltTypeQuals, EltTy);
void *InsertPos = 0;
if (ArrayType *ATP = ArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
return ATP;
// If the element type isn't canonical, this won't be a canonical type either,
// so fill in the canonical type field.
Type *Canonical = 0;
if (!EltTy->isCanonical())
if (!EltTy->isCanonical()) {
Canonical = getArrayType(EltTy.getCanonicalType(), ASM, EltTypeQuals,
NumElts).getTypePtr();
// Get the new insert position for the node we care about.
ArrayType *NewIP = ArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(NewIP == 0 && "Shouldn't be in the map!");
}
Types.push_back(new ArrayType(EltTy, ASM, EltTypeQuals, Canonical));
return Types.back();
ArrayType *New = new ArrayType(EltTy, ASM, EltTypeQuals, Canonical);
ArrayTypes.InsertNode(New, InsertPos);
Types.push_back(New);
return New;
}
/// getFunctionTypeNoProto - Return a K&R style C function type like 'int()'.

View File

@ -79,6 +79,13 @@ void PointerType::Profile(FoldingSetNodeID &ID, TypeRef Pointee) {
ID.AddPointer(Pointee.getAsOpaquePtr());
}
void ArrayType::Profile(FoldingSetNodeID &ID, ArraySizeModifier SizeModifier,
unsigned IndexTypeQuals, TypeRef ElementType) {
ID.AddInteger(SizeModifier);
ID.AddInteger(IndexTypeQuals);
ID.AddPointer(ElementType.getAsOpaquePtr());
}
void FunctionTypeProto::Profile(FoldingSetNodeID &ID, TypeRef Result,
TypeRef* ArgTys,
unsigned NumArgs, bool isVariadic) {
@ -171,7 +178,6 @@ void ArrayType::getAsString(std::string &S) const {
ElementType.getAsString(S);
}
void FunctionTypeNoProto::getAsString(std::string &S) const {
// If needed for precedence reasons, wrap the inner part in grouping parens.
if (!S.empty())

View File

@ -27,8 +27,9 @@ namespace clang {
class ASTContext {
std::vector<Type*> Types;
unsigned NumSlowLookups;
FoldingSet<FunctionTypeProto> FunctionTypeProtos;
FoldingSet<PointerType> PointerTypes;
FoldingSet<ArrayType> ArrayTypes;
FoldingSet<FunctionTypeProto> FunctionTypeProtos;
public:
Preprocessor &PP;
TargetInfo &Target;

View File

@ -246,7 +246,7 @@ public:
/// PointerType - C99 6.7.5.2 - Array Declarators.
///
class ArrayType : public Type {
class ArrayType : public Type, public FoldingSetNode {
public:
/// ArraySizeModifier - Capture whether this is a normal array (e.g. int X[4])
/// an array with a static size (e.g. int X[static 4]), or with a star size
@ -266,6 +266,7 @@ private:
TypeRef ElementType;
/// FIXME: Capture size for VLA or constant size.
/// FIXME: Update Profile()!
/// Use this to implement Type::isIncompleteType.
ArrayType(TypeRef et, ArraySizeModifier sm, unsigned tq, Type *can)
@ -279,6 +280,12 @@ public:
virtual void getAsString(std::string &InnerString) const;
void Profile(FoldingSetNodeID &ID) {
Profile(ID, getSizeModifier(), getIndexTypeQualifier(), getElementType());
}
static void Profile(FoldingSetNodeID &ID, ArraySizeModifier SizeModifier,
unsigned IndexTypeQuals, TypeRef ElementType);
static bool classof(const Type *T) { return T->getTypeClass() == Array; }
static bool classof(const ArrayType *) { return true; }
};