From 6b5a61b6dc400027fd793dcadceeb9da944a37ea Mon Sep 17 00:00:00 2001 From: John McCall Date: Mon, 7 Feb 2011 10:33:21 +0000 Subject: A few more tweaks to the blocks AST representation: - BlockDeclRefExprs always store VarDecls - BDREs no longer store copy expressions - BlockDecls now store a list of captured variables, information about how they're captured, and a copy expression if necessary With that in hand, change IR generation to use the captures data in blocks instead of walking the block independently. Additionally, optimize block layout by emitting fields in descending alignment order, with a heuristic for filling in words when alignment of the end of the block header is insufficient for the most aligned field. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125005 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CodeGenFunction.h | 90 ++++++++++++++++++++++++++++++------------- 1 file changed, 64 insertions(+), 26 deletions(-) (limited to 'lib/CodeGen/CodeGenFunction.h') diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index d1794d0089..d7ea784ee5 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -858,7 +858,8 @@ private: /// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C /// decls. - llvm::DenseMap LocalDeclMap; + typedef llvm::DenseMap DeclMapTy; + DeclMapTy LocalDeclMap; /// LabelMap - This keeps track of the LLVM basic block for each C label. llvm::DenseMap LabelMap; @@ -979,7 +980,7 @@ public: // Block Bits //===--------------------------------------------------------------------===// - llvm::Value *BuildBlockLiteralTmp(const BlockExpr *); + llvm::Value *EmitBlockLiteral(const BlockExpr *); llvm::Constant *BuildDescriptorBlockDecl(const BlockExpr *, const CGBlockInfo &Info, const llvm::StructType *, @@ -987,21 +988,22 @@ public: std::vector *); llvm::Function *GenerateBlockFunction(GlobalDecl GD, - const BlockExpr *BExpr, - CGBlockInfo &Info, + const CGBlockInfo &Info, const Decl *OuterFuncDecl, - llvm::Constant *& BlockVarLayout, - llvm::DenseMap ldm); + const DeclMapTy &ldm); - llvm::Value *LoadBlockStruct(); + llvm::Value *LoadBlockStruct() { + assert(BlockPointer && "no block pointer set!"); + return BlockPointer; + } void AllocateBlockCXXThisPointer(const CXXThisExpr *E); void AllocateBlockDecl(const BlockDeclRefExpr *E); llvm::Value *GetAddrOfBlockDecl(const BlockDeclRefExpr *E) { return GetAddrOfBlockDecl(E->getDecl(), E->isByRef()); } - llvm::Value *GetAddrOfBlockDecl(const ValueDecl *D, bool ByRef); - const llvm::Type *BuildByRefType(const ValueDecl *D); + llvm::Value *GetAddrOfBlockDecl(const VarDecl *var, bool ByRef); + const llvm::Type *BuildByRefType(const VarDecl *var); void GenerateCode(GlobalDecl GD, llvm::Function *Fn); void StartFunction(GlobalDecl GD, QualType RetTy, @@ -2026,32 +2028,68 @@ public: /// Name - The name of the block, kindof. const char *Name; - /// DeclRefs - Variables from parent scopes that have been - /// imported into this block. - llvm::SmallVector DeclRefs; + /// The field index of 'this' within the block, if there is one. + unsigned CXXThisIndex; - /// InnerBlocks - This block and the blocks it encloses. - llvm::SmallPtrSet InnerBlocks; + class Capture { + uintptr_t Data; - /// CXXThisRef - Non-null if 'this' was required somewhere, in - /// which case this is that expression. - const CXXThisExpr *CXXThisRef; + public: + bool isIndex() const { return (Data & 1) != 0; } + bool isConstant() const { return !isIndex(); } + unsigned getIndex() const { assert(isIndex()); return Data >> 1; } + llvm::Value *getConstant() const { + assert(isConstant()); + return reinterpret_cast(Data); + } - /// NeedsObjCSelf - True if something in this block has an implicit - /// reference to 'self'. - bool NeedsObjCSelf : 1; - - /// HasCXXObject - True if block has imported c++ object requiring copy - /// construction in copy helper and destruction in copy dispose helpers. + static Capture makeIndex(unsigned index) { + Capture v; + v.Data = (index << 1) | 1; + return v; + } + + static Capture makeConstant(llvm::Value *value) { + Capture v; + v.Data = reinterpret_cast(value); + return v; + } + }; + + /// The mapping of allocated indexes within the block. + llvm::DenseMap Captures; + + /// CanBeGlobal - True if the block can be global, i.e. it has + /// no non-constant captures. + bool CanBeGlobal : 1; + + /// True if the block needs a custom copy or dispose function. + bool NeedsCopyDispose : 1; + + /// HasCXXObject - True if the block's custom copy/dispose functions + /// need to be run even in GC mode. bool HasCXXObject : 1; + + /// HasWeakBlockVariable - True if block captures a weak __block variable. + bool HasWeakBlockVariable : 1; - /// These are initialized by GenerateBlockFunction. - bool BlockHasCopyDispose : 1; + const llvm::StructType *StructureType; + const BlockExpr *Block; CharUnits BlockSize; CharUnits BlockAlign; llvm::SmallVector BlockLayout; - CGBlockInfo(const char *Name); + const Capture &getCapture(const VarDecl *var) const { + llvm::DenseMap::const_iterator + it = Captures.find(var); + assert(it != Captures.end() && "no entry for variable!"); + return it->second; + } + + const BlockDecl *getBlockDecl() const { return Block->getBlockDecl(); } + const BlockExpr *getBlockExpr() const { return Block; } + + CGBlockInfo(const BlockExpr *blockExpr, const char *Name); }; } // end namespace CodeGen -- cgit v1.2.3-18-g5258