[cfe-commits] r66319 - in /cfe/trunk: lib/CodeGen/CGBlocks.cpp lib/CodeGen/CGBlocks.h lib/CodeGen/CGExprScalar.cpp lib/CodeGen/CodeGenFunction.cpp lib/CodeGen/CodeGenFunction.h test/CodeGen/blocks-1.c

Mike Stump mrs at apple.com
Fri Mar 6 18:35:31 PST 2009


Author: mrs
Date: Fri Mar  6 20:35:30 2009
New Revision: 66319

URL: http://llvm.org/viewvc/llvm-project?rev=66319&view=rev
Log:
Codegen support for copy helpers for block literals.

Modified:
    cfe/trunk/lib/CodeGen/CGBlocks.cpp
    cfe/trunk/lib/CodeGen/CGBlocks.h
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/test/CodeGen/blocks-1.c

Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=66319&r1=66318&r2=66319&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Fri Mar  6 20:35:30 2009
@@ -34,7 +34,8 @@
               llvm::cl::init(false));
 
 llvm::Constant *CodeGenFunction::
-BuildDescriptorBlockDecl(uint64_t Size, const llvm::Type* Ty) {
+BuildDescriptorBlockDecl(uint64_t Size, const llvm::StructType* Ty,
+                         std::vector<HelperInfo> *NoteForHelper) {
   const llvm::Type *UnsignedLongTy
     = CGM.getTypes().ConvertType(getContext().UnsignedLongTy);
   llvm::Constant *C;
@@ -53,10 +54,10 @@
 
   if (BlockHasCopyDispose) {
     // copy_func_helper_decl
-    Elts.push_back(BuildCopyHelper(Ty));
+    Elts.push_back(BuildCopyHelper(Ty, *NoteForHelper));
 
     // destroy_func_decl
-    Elts.push_back(BuildDestroyHelper(Ty));
+    Elts.push_back(BuildDestroyHelper(Ty, *NoteForHelper));
   }
 
   C = llvm::ConstantStruct::get(Elts);
@@ -183,7 +184,7 @@
 
     if (subBlockDeclRefDecls.size() == 0) {
       // __descriptor
-      Elts[4] = BuildDescriptorBlockDecl(subBlockSize, 0);
+      Elts[4] = BuildDescriptorBlockDecl(subBlockSize, 0, 0);
 
       // Optimize to being a global block.
       Elts[0] = CGM.getNSConcreteGlobalBlock();
@@ -202,8 +203,9 @@
     }
 
     std::vector<const llvm::Type *> Types(5+subBlockDeclRefDecls.size());
-    for (int i=0; i<5; ++i)
+    for (int i=0; i<4; ++i)
       Types[i] = Elts[i]->getType();
+    Types[4] = PtrToInt8Ty;
 
     for (unsigned i=0; i < subBlockDeclRefDecls.size(); ++i) {
       const Expr *E = subBlockDeclRefDecls[i];
@@ -216,13 +218,16 @@
         Types[i+5] = ConvertType(Ty);
     }
 
-    llvm::Type *Ty = llvm::StructType::get(Types, true);
+    llvm::StructType *Ty = llvm::StructType::get(Types, true);
 
     llvm::AllocaInst *A = CreateTempAlloca(Ty);
     A->setAlignment(subBlockAlign);
     V = A;
 
-    for (unsigned i=0; i<5; ++i)
+    std::vector<HelperInfo> NoteForHelper(subBlockDeclRefDecls.size());
+    int helpersize = 0;
+
+    for (unsigned i=0; i<4; ++i)
       Builder.CreateStore(Elts[i], Builder.CreateStructGEP(V, i, "block.tmp"));
 
     for (unsigned i=0; i < subBlockDeclRefDecls.size(); ++i)
@@ -240,15 +245,24 @@
         VD = BDRE->getDecl();
 
         llvm::Value* Addr = Builder.CreateStructGEP(V, i+5, "tmp");
-        // FIXME: I want a better way to do this.
+        NoteForHelper[helpersize].index = i+5;
+        NoteForHelper[helpersize].RequiresCopying = BlockRequiresCopying(VD->getType());
+        NoteForHelper[helpersize].flag
+          = VD->getType()->isBlockPointerType() ? BLOCK_FIELD_IS_BLOCK : BLOCK_FIELD_IS_OBJECT;
+
         if (LocalDeclMap[VD]) {
           if (BDRE->isByRef()) {
+            // FIXME: For only local, or all byrefs?
+            NoteForHelper[helpersize].flag = BLOCK_FIELD_IS_BYREF |
+              (0?BLOCK_FIELD_IS_WEAK : 0);
+            // FIXME: Add weak support
             const llvm::Type *Ty = Types[i+5];
             llvm::Value *Loc = LocalDeclMap[VD];
             Loc = Builder.CreateStructGEP(Loc, 1, "forwarding");
             Loc = Builder.CreateLoad(Loc, false);
             Loc = Builder.CreateBitCast(Loc, Ty);
             Builder.CreateStore(Loc, Addr);
+            ++helpersize;
             continue;
           } else
             E = new (getContext()) DeclRefExpr (cast<NamedDecl>(VD),
@@ -261,6 +275,7 @@
                           getContext().getPointerType(E->getType()),
                           SourceLocation());
         }
+        ++helpersize;
 
         RValue r = EmitAnyExpr(E, Addr, false);
         if (r.isScalar()) {
@@ -296,9 +311,13 @@
         // FIXME: Ensure that the offset created by the backend for
         // the struct matches the previously computed offset in BlockDecls.
       }
+    NoteForHelper.resize(helpersize);
 
     // __descriptor
-    Elts[4] = BuildDescriptorBlockDecl(subBlockSize, Ty);
+    llvm::Value *Descriptor = BuildDescriptorBlockDecl(subBlockSize, Ty,
+                                                       &NoteForHelper);
+    Descriptor = Builder.CreateBitCast(Descriptor, PtrToInt8Ty);
+    Builder.CreateStore(Descriptor, Builder.CreateStructGEP(V, 4, "block.tmp"));
   }
 
   QualType BPT = BE->getType();
@@ -636,7 +655,7 @@
   return Fn;
 }
 
-uint64_t CodeGenFunction::getBlockOffset(const BlockDeclRefExpr *BDRE) {
+uint64_t BlockFunction::getBlockOffset(const BlockDeclRefExpr *BDRE) {
   const ValueDecl *D = dyn_cast<ValueDecl>(BDRE->getDecl());
 
   uint64_t Size = getContext().getTypeSize(D->getType()) / 8;
@@ -675,15 +694,20 @@
   return BlockOffset-Size;
 }
 
-llvm::Constant *BlockFunction::GenerateCopyHelperFunction(const llvm::Type *Ty) {
+llvm::Constant *BlockFunction::
+GenerateCopyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType *T,
+                           std::vector<HelperInfo> &NoteForHelper) {
   QualType R = getContext().VoidTy;
 
   FunctionArgList Args;
   // FIXME: This leaks
+  ImplicitParamDecl *Dst =
+    ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0,
+                              getContext().getPointerType(getContext().VoidTy));
+  Args.push_back(std::make_pair(Dst, Dst->getType()));
   ImplicitParamDecl *Src =
     ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0,
                               getContext().getPointerType(getContext().VoidTy));
-
   Args.push_back(std::make_pair(Src, Src->getType()));
   
   const CGFunctionInfo &FI =
@@ -707,14 +731,46 @@
                                           FunctionDecl::Static, false,
                                           true);
   CGF.StartFunction(FD, R, Fn, Args, SourceLocation());
-  // EmitStmt(BExpr->getBody());
+
+  llvm::Value *SrcObj = CGF.GetAddrOfLocalVar(Src);
+  llvm::Type *PtrPtrT;
+  PtrPtrT = llvm::PointerType::get(llvm::PointerType::get(T, 0), 0);
+  SrcObj = Builder.CreateBitCast(SrcObj, PtrPtrT);
+  SrcObj = Builder.CreateLoad(SrcObj);
+
+  llvm::Value *DstObj = CGF.GetAddrOfLocalVar(Dst);
+  DstObj = Builder.CreateBitCast(DstObj, llvm::PointerType::get(T, 0));
+
+  for (unsigned i=0; i < NoteForHelper.size(); ++i) {
+    int flag = NoteForHelper[i].flag;
+    int index = NoteForHelper[i].index;
+
+    if ((NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF)
+        || NoteForHelper[i].RequiresCopying) {
+      llvm::Value *Srcv = SrcObj;
+      Srcv = Builder.CreateStructGEP(Srcv, index);
+      Srcv = Builder.CreateBitCast(Srcv,
+                                   llvm::PointerType::get(PtrToInt8Ty, 0));
+      Srcv = Builder.CreateLoad(Srcv);
+
+      llvm::Value *Dstv = Builder.CreateStructGEP(DstObj, index);
+      Dstv = Builder.CreateBitCast(Dstv, PtrToInt8Ty);
+
+      llvm::Value *N = llvm::ConstantInt::get(llvm::Type::Int32Ty, flag);
+      llvm::Value *F = getBlockObjectAssign();
+      Builder.CreateCall3(F, Dstv, Srcv, N);
+    }
+  }
+
   CGF.FinishFunction();
 
   return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty);
 }
 
 llvm::Constant *BlockFunction::
-GenerateDestroyHelperFunction(const llvm::Type* Ty) {
+GenerateDestroyHelperFunction(bool BlockHasCopyDispose,
+                              const llvm::StructType* T,
+                              std::vector<HelperInfo> &NoteForHelper) {
   QualType R = getContext().VoidTy;
 
   FunctionArgList Args;
@@ -752,12 +808,16 @@
   return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty);
 }
 
-llvm::Constant *BlockFunction::BuildCopyHelper(const llvm::Type *Ty) {
-  return CodeGenFunction(CGM).GenerateCopyHelperFunction(Ty);
+llvm::Constant *BlockFunction::BuildCopyHelper(const llvm::StructType *T,
+                                       std::vector<HelperInfo> &NoteForHelper) {
+  return CodeGenFunction(CGM).GenerateCopyHelperFunction(BlockHasCopyDispose,
+                                                         T, NoteForHelper);
 }
 
-llvm::Constant *BlockFunction::BuildDestroyHelper(const llvm::Type *Ty) {
-  return CodeGenFunction(CGM).GenerateDestroyHelperFunction(Ty);
+llvm::Constant *BlockFunction::BuildDestroyHelper(const llvm::StructType *T,
+                                       std::vector<HelperInfo> &NoteForHelper) {
+  return CodeGenFunction(CGM).GenerateDestroyHelperFunction(BlockHasCopyDispose,
+                                                            T, NoteForHelper);
 }
 
 llvm::Constant *BlockFunction::
@@ -924,3 +984,11 @@
 }
 
 ASTContext &BlockFunction::getContext() const { return CGM.getContext(); }
+
+BlockFunction::BlockFunction(CodeGenModule &cgm, CodeGenFunction &cgf,
+                             CGBuilderTy &B)
+  : CGM(cgm), CGF(cgf), Builder(B) {
+  PtrToInt8Ty = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
+
+  BlockHasCopyDispose = false;
+}

Modified: cfe/trunk/lib/CodeGen/CGBlocks.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.h?rev=66319&r1=66318&r2=66319&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.h (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.h Fri Mar  6 20:35:30 2009
@@ -103,7 +103,8 @@
     : Context(C), TheModule(M), TheTargetData(TD), Types(T),
       CGM(CodeGen),
       NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), BlockDescriptorType(0),
-      GenericBlockLiteralType(0), BlockObjectAssign(0), BlockObjectDispose(0) {
+      GenericBlockLiteralType(0), GenericExtendedBlockLiteralType(0),
+      BlockObjectAssign(0), BlockObjectDispose(0) {
     Block.GlobalUniqueCount = 0;
     PtrToInt8Ty = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
   }
@@ -116,6 +117,12 @@
 
 public:
   const llvm::Type *PtrToInt8Ty;
+  struct HelperInfo {
+    int index;
+    int flag;
+    bool RequiresCopying;
+  };
+
   enum {
     BLOCK_FIELD_IS_OBJECT   =  3,  /* id, NSObject, __attribute__((NSObject)),
                                       block, ... */
@@ -150,19 +157,40 @@
 
   CGBuilderTy &Builder;
 
-  BlockFunction(CodeGenModule &cgm, CodeGenFunction &cgf, CGBuilderTy &B)
-    : CGM(cgm), CGF(cgf), Builder(B) {
-    PtrToInt8Ty = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
-  }
+  BlockFunction(CodeGenModule &cgm, CodeGenFunction &cgf, CGBuilderTy &B);
+
+  /// BlockOffset - The offset in bytes for the next allocation of an
+  /// imported block variable.
+  uint64_t BlockOffset;
+  /// BlockAlign - Maximal alignment needed for the Block expressed in bytes.
+  uint64_t BlockAlign;
+
+  /// getBlockOffset - Allocate an offset for the ValueDecl from a
+  /// BlockDeclRefExpr in a block literal (BlockExpr).
+  uint64_t getBlockOffset(const BlockDeclRefExpr *E);
+
+  /// BlockHasCopyDispose - True iff the block uses copy/dispose.
+  bool BlockHasCopyDispose;
+
+  /// BlockDeclRefDecls - Decls from BlockDeclRefExprs in apperance order
+  /// in a block literal.  Decls without names are used for padding.
+  llvm::SmallVector<const Expr *, 8> BlockDeclRefDecls;
+
+  /// BlockDecls - Offsets for all Decls in BlockDeclRefExprs.
+  std::map<const Decl*, uint64_t> BlockDecls;
 
   ImplicitParamDecl *BlockStructDecl;
   ImplicitParamDecl *getBlockStructDecl() { return BlockStructDecl; }
 
-  llvm::Constant *GenerateCopyHelperFunction(const llvm::Type *);
-  llvm::Constant *GenerateDestroyHelperFunction(const llvm::Type *);
-
-  llvm::Constant *BuildCopyHelper(const llvm::Type *);
-  llvm::Constant *BuildDestroyHelper(const llvm::Type *);
+  llvm::Constant *GenerateCopyHelperFunction(bool, const llvm::StructType *,
+                                             std::vector<HelperInfo> &);
+  llvm::Constant *GenerateDestroyHelperFunction(bool, const llvm::StructType *,
+                                                std::vector<HelperInfo> &);
+
+  llvm::Constant *BuildCopyHelper(const llvm::StructType *,
+                                  std::vector<HelperInfo> &);
+  llvm::Constant *BuildDestroyHelper(const llvm::StructType *,
+                                     std::vector<HelperInfo> &);
 
   llvm::Constant *GeneratebyrefCopyHelperFunction(const llvm::Type *, int flag);
   llvm::Constant *GeneratebyrefDestroyHelperFunction(const llvm::Type *T, int);

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=66319&r1=66318&r2=66319&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Fri Mar  6 20:35:30 2009
@@ -1326,8 +1326,7 @@
 }
 
 Value *ScalarExprEmitter::VisitBlockExpr(const BlockExpr *BE) {
-  llvm::Value *V = CGF.BuildBlockLiteralTmp(BE);
-  return V;
+  return CGF.BuildBlockLiteralTmp(BE);
 }
 
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=66319&r1=66318&r2=66319&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Fri Mar  6 20:35:30 2009
@@ -32,7 +32,6 @@
 
   // FIXME: We need to rearrange the code for copy/dispose so we have this
   // sooner, so we can calculate offsets correctly.
-  BlockHasCopyDispose = false;
   if (!BlockHasCopyDispose)
     BlockOffset = CGM.getTargetData()
       .getTypeStoreSizeInBits(CGM.getGenericBlockLiteralType()) / 8;

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=66319&r1=66318&r2=66319&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Fri Mar  6 20:35:30 2009
@@ -266,7 +266,9 @@
   //===--------------------------------------------------------------------===//
 
   llvm::Value *BuildBlockLiteralTmp(const BlockExpr *);
-  llvm::Constant *BuildDescriptorBlockDecl(uint64_t Size, const llvm::Type *);
+  llvm::Constant *BuildDescriptorBlockDecl(uint64_t Size,
+                                           const llvm::StructType *,
+                                           std::vector<HelperInfo> *);
 
   llvm::Function *GenerateBlockFunction(const BlockExpr *BExpr,
                                         const BlockInfo& Info,
@@ -276,26 +278,6 @@
 
   llvm::Value *LoadBlockStruct();
 
-  /// BlockHasCopyDispose - True iff the block uses copy/dispose.
-  bool BlockHasCopyDispose;
-
-  /// BlockDeclRefDecls - Decls from BlockDeclRefExprs in apperance order
-  /// in a block literal.  Decls without names are used for padding.
-  llvm::SmallVector<const Expr *, 8> BlockDeclRefDecls;
-
-  /// BlockOffset - The offset in bytes for the next allocation of an
-  /// imported block variable.
-  uint64_t BlockOffset;
-  /// BlockAlign - Maximal alignment needed for the Block expressed in bytes.
-  uint64_t BlockAlign;
-
-  /// getBlockOffset - Allocate an offset for the ValueDecl from a
-  /// BlockDeclRefExpr in a block literal (BlockExpr).
-  uint64_t getBlockOffset(const BlockDeclRefExpr *E);
-
-  /// BlockDecls - Offsets for all Decls in BlockDeclRefExprs.
-  std::map<const Decl*, uint64_t> BlockDecls;
-
   llvm::Value *GetAddrOfBlockDecl(const BlockDeclRefExpr *E);
 
   const llvm::Type *BuildByRefType(QualType Ty, uint64_t Align);

Modified: cfe/trunk/test/CodeGen/blocks-1.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/blocks-1.c?rev=66319&r1=66318&r2=66319&view=diff

==============================================================================
--- cfe/trunk/test/CodeGen/blocks-1.c (original)
+++ cfe/trunk/test/CodeGen/blocks-1.c Fri Mar  6 20:35:30 2009
@@ -5,7 +5,7 @@
 // RUN: grep "__Block_byref_id_object_copy_" %t | count 2 &&
 // RUN: grep "__Block_byref_id_object_dispose_" %t | count 2 &&
 // RUN: grep "i32 135)" %t | count 2 &&
-// RUN: grep "_Block_object_assign" %t | count 2
+// RUN: grep "_Block_object_assign" %t | count 6
 
 #include <stdio.h>
 





More information about the cfe-commits mailing list