]> granicus.if.org Git - clang/commitdiff
Cache llvm::Type through PATypeHolder.
authorDevang Patel <dpatel@apple.com>
Thu, 25 Oct 2007 18:32:36 +0000 (18:32 +0000)
committerDevang Patel <dpatel@apple.com>
Thu, 25 Oct 2007 18:32:36 +0000 (18:32 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43355 91177308-0d34-0410-b5e6-96231b3b80d8

CodeGen/CodeGenTypes.cpp
CodeGen/CodeGenTypes.h

index 31c76b3306a6629f4c9364060903384e8325d1cd..0b225291d254d794e2e4d55ce6bec16489d06961 100644 (file)
@@ -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<Type *, llvm::PATypeHolder *>::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);
+    }
   }
 }
 
index de20173d9317e4dae07aa8e22be05ffd341864d2..7f2641146dfaf37b0045dde69676985dd5228813 100644 (file)
@@ -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<const RecordDecl *, llvm::Type *> 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<Type *, llvm::PATypeHolder *> 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<const llvm::Type*> &ArgTys);