From: Devang Patel Date: Thu, 25 Oct 2007 18:32:36 +0000 (+0000) Subject: Cache llvm::Type through PATypeHolder. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=30ec9972be5a5af1f7a2277360dfa3aa1540b4fa;p=clang Cache llvm::Type through PATypeHolder. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43355 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/CodeGen/CodeGenTypes.cpp b/CodeGen/CodeGenTypes.cpp index 31c76b3306..0b225291d2 100644 --- a/CodeGen/CodeGenTypes.cpp +++ b/CodeGen/CodeGenTypes.cpp @@ -69,7 +69,21 @@ CodeGenTypes::~CodeGenTypes() { /// ConvertType - Convert the specified type to its LLVM form. const llvm::Type *CodeGenTypes::ConvertType(QualType T) { - // FIXME: Cache these, move the CodeGenModule, expand, etc. + // See if type is already cached. + llvm::DenseMap::iterator + I = TypeHolderMap.find(T.getTypePtr()); + if (I != TypeHolderMap.end()) { + llvm::PATypeHolder *PAT = I->second; + return PAT->get(); + } + + const llvm::Type *ResultType = ConvertNewType(T); + llvm::PATypeHolder *PAT = new llvm::PATypeHolder(ResultType); + TypeHolderMap[T.getTypePtr()] = PAT; + return ResultType; +} + +const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { const clang::Type &Ty = *T.getCanonicalType(); switch (Ty.getTypeClass()) { @@ -166,7 +180,10 @@ const llvm::Type *CodeGenTypes::ConvertType(QualType T) { // Struct return passes the struct byref. if (!ResultType->isFirstClassType() && ResultType != llvm::Type::VoidTy) { - ArgTys.push_back(llvm::PointerType::get(ResultType)); + const llvm::Type *RType = llvm::PointerType::get(ResultType); + QualType RTy = Context.getPointerType(FP.getResultType()); + TypeHolderMap[RTy.getTypePtr()] = new llvm::PATypeHolder(RType); + ArgTys.push_back(RType); ResultType = llvm::Type::VoidTy; } @@ -215,6 +232,8 @@ const llvm::Type *CodeGenTypes::ConvertType(QualType T) { // Reevaluate this when performance analyis finds tons of opaque types. llvm::OpaqueType *OpaqueTy = llvm::OpaqueType::get(); RecordTypesToResolve[RD] = OpaqueTy; + QualType Opq; + TypeHolderMap[Opq.getTypePtr()] = new llvm::PATypeHolder(OpaqueTy); // Layout fields. RecordOrganizer RO; @@ -281,8 +300,12 @@ void CodeGenTypes::DecodeArgumentTypes(const FunctionTypeProto &FTP, const llvm::Type *Ty = ConvertType(FTP.getArgType(i)); if (Ty->isFirstClassType()) ArgTys.push_back(Ty); - else - ArgTys.push_back(llvm::PointerType::get(Ty)); + else { + QualType PTy = Context.getPointerType(FTP.getArgType(i)); + const llvm::Type *PtrTy = llvm::PointerType::get(Ty); + TypeHolderMap[PTy.getTypePtr()] = new llvm::PATypeHolder(PtrTy); + ArgTys.push_back(PtrTy); + } } } diff --git a/CodeGen/CodeGenTypes.h b/CodeGen/CodeGenTypes.h index de20173d93..7f2641146d 100644 --- a/CodeGen/CodeGenTypes.h +++ b/CodeGen/CodeGenTypes.h @@ -20,6 +20,7 @@ namespace llvm { class Module; class Type; + class PATypeHolder; } namespace clang { @@ -27,6 +28,7 @@ namespace clang { class TagDecl; class TargetInfo; class QualType; + class Type; class FunctionTypeProto; class FieldDecl; class RecordDecl; @@ -77,12 +79,18 @@ class CodeGenTypes { /// record. llvm::DenseMap RecordTypesToResolve; + /// TypeHolderMap - This map keeps cache of llvm::Types (through PATypeHolder) + /// and maps llvm::Types to corresponding clang::Type. llvm::PATypeHolder is + /// used instead of llvm::Type because it allows us to bypass potential + /// dangling type pointers due to type refinement on llvm side. + llvm::DenseMap TypeHolderMap; public: CodeGenTypes(ASTContext &Ctx, llvm::Module &M); ~CodeGenTypes(); TargetInfo &getTarget() const { return Target; } + const llvm::Type *ConvertNewType(QualType T); const llvm::Type *ConvertType(QualType T); void DecodeArgumentTypes(const FunctionTypeProto &FTP, std::vector &ArgTys);