diff options
author | Daniel Dunbar <daniel@zuster.org> | 2010-03-31 01:09:11 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2010-03-31 01:09:11 +0000 |
commit | 198bcb44b6271c92fd856403f34b518828100aac (patch) | |
tree | d56190a685030b67dd428e3fc6024e8d3841d4e9 | |
parent | 490fc902710eca4e4a07b2ecaa223e70670331d6 (diff) |
IRGen: Move the auxiliary data structures tracking AST -> LLVM mappings out of CodeGenTypes, to per-record CGRecordLayout structures.
- 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
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 13 | ||||
-rw-r--r-- | lib/CodeGen/CGExprConstant.cpp | 8 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 7 | ||||
-rw-r--r-- | lib/CodeGen/CGRecordLayout.h | 51 | ||||
-rw-r--r-- | lib/CodeGen/CGRecordLayoutBuilder.cpp | 10 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTypes.cpp | 29 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTypes.h | 33 |
7 files changed, 75 insertions, 76 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 027264f25b..87ec159a60 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -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"); diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index c86c6aa2d6..172a77d78e 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -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); diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 1ed41d005f..883ed98511 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -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)); diff --git a/lib/CodeGen/CGRecordLayout.h b/lib/CodeGen/CGRecordLayout.h index 7581cdbd8f..d0d8f984a9 100644 --- a/lib/CodeGen/CGRecordLayout.h +++ b/lib/CodeGen/CGRecordLayout.h @@ -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 diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp index 3ddf1b58d5..daebabddc6 100644 --- a/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -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; } diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp index 8f341b51fb..f53dd83d70 100644 --- a/lib/CodeGen/CodeGenTypes.cpp +++ b/lib/CodeGen/CodeGenTypes.cpp @@ -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 { diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h index 22d0671337..70166b1e22 100644 --- a/lib/CodeGen/CodeGenTypes.h +++ b/lib/CodeGen/CodeGenTypes.h @@ -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); |