[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