]> granicus.if.org Git - clang/commitdiff
IRGen: Move the auxiliary data structures tracking AST -> LLVM mappings out of CodeGe...
authorDaniel Dunbar <daniel@zuster.org>
Wed, 31 Mar 2010 01:09:11 +0000 (01:09 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Wed, 31 Mar 2010 01:09:11 +0000 (01:09 +0000)
 - I did a cursory check that this was perf neutral, FWIW.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99978 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprConstant.cpp
lib/CodeGen/CGObjCMac.cpp
lib/CodeGen/CGRecordLayout.h
lib/CodeGen/CGRecordLayoutBuilder.cpp
lib/CodeGen/CodeGenTypes.cpp
lib/CodeGen/CodeGenTypes.h

index 027264f25bbfa37babbdb9bd34e277e4d0d361e1..87ec159a60109691e6996591d4abf1e76534308a 100644 (file)
@@ -14,6 +14,7 @@
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
 #include "CGCall.h"
+#include "CGRecordLayout.h"
 #include "CGObjCRuntime.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
@@ -1468,7 +1469,9 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
 LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value* BaseValue,
                                               const FieldDecl* Field,
                                               unsigned CVRQualifiers) {
-  CodeGenTypes::BitFieldInfo Info = CGM.getTypes().getBitFieldInfo(Field);
+  const CGRecordLayout &RL =
+    CGM.getTypes().getCGRecordLayout(Field->getParent());
+  const CGRecordLayout::BitFieldInfo &Info = RL.getBitFieldInfo(Field);
 
   // FIXME: CodeGenTypes should expose a method to get the appropriate type for
   // FieldTy (the appropriate type is ABI-dependent).
@@ -1496,7 +1499,9 @@ LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue,
   if (Field->isBitField())
     return EmitLValueForBitfield(BaseValue, Field, CVRQualifiers);
 
-  unsigned idx = CGM.getTypes().getLLVMFieldNo(Field);
+  const CGRecordLayout &RL =
+    CGM.getTypes().getCGRecordLayout(Field->getParent());
+  unsigned idx = RL.getLLVMFieldNo(Field);
   llvm::Value *V = Builder.CreateStructGEP(BaseValue, idx, "tmp");
 
   // Match union field type.
@@ -1531,7 +1536,9 @@ CodeGenFunction::EmitLValueForFieldInitialization(llvm::Value* BaseValue,
   if (!FieldType->isReferenceType())
     return EmitLValueForField(BaseValue, Field, CVRQualifiers);
 
-  unsigned idx = CGM.getTypes().getLLVMFieldNo(Field);
+  const CGRecordLayout &RL =
+    CGM.getTypes().getCGRecordLayout(Field->getParent());
+  unsigned idx = RL.getLLVMFieldNo(Field);
   llvm::Value *V = Builder.CreateStructGEP(BaseValue, idx, "tmp");
 
   assert(!FieldType.getObjCGCAttr() && "fields cannot have GC attrs");
index c86c6aa2d6509b100975f066990b77d7645290ee..172a77d78e5fbb2dd94ff068c03591b2fdd39208 100644 (file)
@@ -1012,7 +1012,9 @@ llvm::Constant *CodeGenModule::EmitNullConstant(QualType T) {
          E = RD->field_end(); I != E; ++I) {
       const FieldDecl *FD = *I;
       
-      unsigned FieldNo = getTypes().getLLVMFieldNo(FD);
+      const CGRecordLayout &RL =
+        getTypes().getCGRecordLayout(FD->getParent());
+      unsigned FieldNo = RL.getLLVMFieldNo(FD);
       Elements[FieldNo] = EmitNullConstant(FD->getType());
     }
     
@@ -1048,7 +1050,9 @@ CodeGenModule::EmitPointerToDataMember(const FieldDecl *FD) {
   const llvm::StructType *ClassLTy =
     cast<llvm::StructType>(getTypes().ConvertType(ClassType));
 
-  unsigned FieldNo = getTypes().getLLVMFieldNo(FD);
+  const CGRecordLayout &RL =
+    getTypes().getCGRecordLayout(FD->getParent());
+  unsigned FieldNo = RL.getLLVMFieldNo(FD);
   uint64_t Offset = 
     getTargetData().getStructLayout(ClassLTy)->getElementOffset(FieldNo);
 
index 1ed41d005f324c121b95bc4ab89d85f32216a648..883ed98511e7242ff2671ffc223af2177598c8c4 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "CGObjCRuntime.h"
 
+#include "CGRecordLayout.h"
 #include "CodeGenModule.h"
 #include "CodeGenFunction.h"
 #include "clang/AST/ASTContext.h"
@@ -3134,8 +3135,10 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
     FieldDecl *Field = RecFields[i];
     uint64_t FieldOffset;
     if (RD) {
+      const CGRecordLayout &RL =
+        CGM.getTypes().getCGRecordLayout(Field->getParent());
       if (Field->isBitField()) {
-        CodeGenTypes::BitFieldInfo Info = CGM.getTypes().getBitFieldInfo(Field);
+        const CGRecordLayout::BitFieldInfo &Info = RL.getBitFieldInfo(Field);
 
         const llvm::Type *Ty =
           CGM.getTypes().ConvertTypeForMemRecursive(Field->getType());
@@ -3144,7 +3147,7 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
         FieldOffset = Info.FieldNo * TypeSize;
       } else
         FieldOffset =
-          Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field));
+          Layout->getElementOffset(RL.getLLVMFieldNo(Field));
     } else
       FieldOffset = ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field));
 
index 7581cdbd8f17c09121bbb531bc29394ff20b97c9..d0d8f984a9efaed712cfa17535e08626633532bd 100644 (file)
@@ -10,6 +10,8 @@
 #ifndef CLANG_CODEGEN_CGRECORDLAYOUT_H
 #define CLANG_CODEGEN_CGRECORDLAYOUT_H
 
+#include "llvm/ADT/DenseMap.h"
+#include "clang/AST/Decl.h"
 namespace llvm {
   class Type;
 }
@@ -19,31 +21,72 @@ namespace CodeGen {
 
 /// CGRecordLayout - This class handles struct and union layout info while
 /// lowering AST types to LLVM types.
+///
+/// These layout objects are only created on demand as IR generation requires.
 class CGRecordLayout {
+  friend class CodeGenTypes;
+
   CGRecordLayout(const CGRecordLayout&); // DO NOT IMPLEMENT
   void operator=(const CGRecordLayout&); // DO NOT IMPLEMENT
 
+public:
+  struct BitFieldInfo {
+    BitFieldInfo(unsigned FieldNo,
+                 unsigned Start,
+                 unsigned Size)
+      : FieldNo(FieldNo), Start(Start), Size(Size) {}
+
+    unsigned FieldNo;
+    unsigned Start;
+    unsigned Size;
+  };
+
+private:
   /// The LLVMType corresponding to this record layout.
   const llvm::Type *LLVMType;
 
+  /// Map from (non-bit-field) struct field to the corresponding llvm struct
+  /// type field no. This info is populated by record builder.
+  llvm::DenseMap<const FieldDecl *, unsigned> FieldInfo;
+
+  /// Map from (bit-field) struct field to the corresponding llvm struct type
+  /// field no. This info is populated by record builder.
+  llvm::DenseMap<const FieldDecl *, BitFieldInfo> BitFields;
+
   /// Whether one of the fields in this record layout is a pointer to data
   /// member, or a struct that contains pointer to data member.
-  bool ContainsPointerToDataMember;
+  bool ContainsPointerToDataMember : 1;
 
 public:
   CGRecordLayout(const llvm::Type *T, bool ContainsPointerToDataMember)
     : LLVMType(T), ContainsPointerToDataMember(ContainsPointerToDataMember) {}
 
-  /// getLLVMType - Return llvm type associated with this record.
+  /// \brief Return the LLVM type associated with this record.
   const llvm::Type *getLLVMType() const {
     return LLVMType;
   }
 
-  /// containsPointerToDataMember - Whether this struct contains pointers to
-  /// data members.
+  /// \brief Check whether this struct contains pointers to data members.
   bool containsPointerToDataMember() const {
     return ContainsPointerToDataMember;
   }
+
+  /// \brief Return the BitFieldInfo that corresponds to the field FD.
+  unsigned getLLVMFieldNo(const FieldDecl *FD) const {
+    assert(!FD->isBitField() && "Invalid call for bit-field decl!");
+    assert(FieldInfo.count(FD) && "Invalid field for record!");
+    return FieldInfo.lookup(FD);
+  }
+
+  /// \brief Return llvm::StructType element number that corresponds to the
+  /// field FD.
+  const BitFieldInfo &getBitFieldInfo(const FieldDecl *FD) const {
+    assert(FD->isBitField() && "Invalid call for non bit-field decl!");
+    llvm::DenseMap<const FieldDecl *, BitFieldInfo>::const_iterator
+      it = BitFields.find(FD);
+    assert(it != BitFields.end()  && "Unable to find bitfield info");
+    return it->second;
+  }
 };
 
 }  // end namespace CodeGen
index 3ddf1b58d5a3f82454ad693a0843ca2b3e9976bf..daebabddc61fb832082969efa536f684cdb65e3f 100644 (file)
@@ -490,12 +490,15 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D) {
          getTargetData().getTypeAllocSize(Ty) &&
          "Type size mismatch!");
 
+  CGRecordLayout *RL =
+    new CGRecordLayout(Ty, Builder.ContainsPointerToDataMember);
+
   // Add all the field numbers.
   for (unsigned i = 0, e = Builder.LLVMFields.size(); i != e; ++i) {
     const FieldDecl *FD = Builder.LLVMFields[i].first;
     unsigned FieldNo = Builder.LLVMFields[i].second;
 
-    addFieldInfo(FD, FieldNo);
+    RL->FieldInfo.insert(std::make_pair(FD, FieldNo));
   }
 
   // Add bitfield info.
@@ -503,8 +506,9 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D) {
     const CGRecordLayoutBuilder::LLVMBitFieldInfo &Info =
       Builder.LLVMBitFields[i];
 
-    addBitFieldInfo(Info.FD, Info.FieldNo, Info.Start, Info.Size);
+    CGRecordLayout::BitFieldInfo BFI(Info.FieldNo, Info.Start, Info.Size);
+    RL->BitFields.insert(std::make_pair(Info.FD, BFI));
   }
 
-  return new CGRecordLayout(Ty, Builder.ContainsPointerToDataMember);
+  return RL;
 }
index 8f341b51fb20b99b763a7c5330a0cbdb6589ee8c..f53dd83d7035193912b1c7050cda0ec72e693bab 100644 (file)
@@ -459,35 +459,6 @@ const llvm::Type *CodeGenTypes::ConvertTagDeclType(const TagDecl *TD) {
   return ResultHolder.get();
 }
 
-/// getLLVMFieldNo - Return llvm::StructType element number
-/// that corresponds to the field FD.
-unsigned CodeGenTypes::getLLVMFieldNo(const FieldDecl *FD) {
-  assert(!FD->isBitField() && "Don't use getLLVMFieldNo on bit fields!");
-
-  llvm::DenseMap<const FieldDecl*, unsigned>::iterator I = FieldInfo.find(FD);
-  assert (I != FieldInfo.end()  && "Unable to find field info");
-  return I->second;
-}
-
-/// addFieldInfo - Assign field number to field FD.
-void CodeGenTypes::addFieldInfo(const FieldDecl *FD, unsigned No) {
-  FieldInfo[FD] = No;
-}
-
-/// getBitFieldInfo - Return the BitFieldInfo that corresponds to the field FD.
-CodeGenTypes::BitFieldInfo CodeGenTypes::getBitFieldInfo(const FieldDecl *FD) {
-  llvm::DenseMap<const FieldDecl *, BitFieldInfo>::iterator
-    I = BitFields.find(FD);
-  assert (I != BitFields.end()  && "Unable to find bitfield info");
-  return I->second;
-}
-
-/// addBitFieldInfo - Assign a start bit and a size to field FD.
-void CodeGenTypes::addBitFieldInfo(const FieldDecl *FD, unsigned FieldNo,
-                                   unsigned Start, unsigned Size) {
-  BitFields.insert(std::make_pair(FD, BitFieldInfo(FieldNo, Start, Size)));
-}
-
 /// getCGRecordLayout - Return record layout info for the given llvm::Type.
 const CGRecordLayout &
 CodeGenTypes::getCGRecordLayout(const RecordDecl *TD) const {
index 22d06713377c4b56abfaec739a7bf6388a3713e8..70166b1e22728c7d524b3883855c03262350bcfc 100644 (file)
@@ -81,28 +81,10 @@ class CodeGenTypes {
   /// record layout info.
   llvm::DenseMap<const Type*, CGRecordLayout *> CGRecordLayouts;
 
-  /// FieldInfo - This maps struct field with corresponding llvm struct type
-  /// field no. This info is populated by record organizer.
-  llvm::DenseMap<const FieldDecl *, unsigned> FieldInfo;
-
   /// FunctionInfos - Hold memoized CGFunctionInfo results.
   llvm::FoldingSet<CGFunctionInfo> FunctionInfos;
 
-public:
-  struct BitFieldInfo {
-    BitFieldInfo(unsigned FieldNo,
-                 unsigned Start,
-                 unsigned Size)
-      : FieldNo(FieldNo), Start(Start), Size(Size) {}
-
-    unsigned FieldNo;
-    unsigned Start;
-    unsigned Size;
-  };
-
 private:
-  llvm::DenseMap<const FieldDecl *, BitFieldInfo> BitFields;
-
   /// TypeCache - 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
@@ -150,10 +132,6 @@ public:
                                                      
   const CGRecordLayout &getCGRecordLayout(const RecordDecl*) const;
 
-  /// getLLVMFieldNo - Return llvm::StructType element number
-  /// that corresponds to the field FD.
-  unsigned getLLVMFieldNo(const FieldDecl *FD);
-
   /// UpdateCompletedType - When we find the full definition for a TagDecl,
   /// replace the 'opaque' type we previously made for it if applicable.
   void UpdateCompletedType(const TagDecl *TD);
@@ -202,17 +180,6 @@ public:
   CGRecordLayout *ComputeRecordLayout(const RecordDecl *D);
 
 public:  // These are internal details of CGT that shouldn't be used externally.
-  /// addFieldInfo - Assign field number to field FD.
-  void addFieldInfo(const FieldDecl *FD, unsigned FieldNo);
-
-  /// addBitFieldInfo - Assign a start bit and a size to field FD.
-  void addBitFieldInfo(const FieldDecl *FD, unsigned FieldNo,
-                       unsigned Start, unsigned Size);
-
-  /// getBitFieldInfo - Return the BitFieldInfo  that corresponds to the field
-  /// FD.
-  BitFieldInfo getBitFieldInfo(const FieldDecl *FD);
-
   /// ConvertTagDeclType - Lay out a tagged decl type like struct or union or
   /// enum.
   const llvm::Type *ConvertTagDeclType(const TagDecl *TD);