[cfe-commits] r81602 - in /cfe/trunk: lib/CodeGen/CGBlocks.cpp lib/CodeGen/CGDecl.cpp lib/CodeGen/CGExpr.cpp test/CodeGen/blocks-aligned-byref-variable.c
Anders Carlsson
andersca at mac.com
Fri Sep 11 19:44:18 PDT 2009
Author: andersca
Date: Fri Sep 11 21:44:18 2009
New Revision: 81602
URL: http://llvm.org/viewvc/llvm-project?rev=81602&view=rev
Log:
Add support for __block variables with alignment greater than __alignof(void *).
Added:
cfe/trunk/test/CodeGen/blocks-aligned-byref-variable.c
Modified:
cfe/trunk/lib/CodeGen/CGBlocks.cpp
cfe/trunk/lib/CodeGen/CGDecl.cpp
cfe/trunk/lib/CodeGen/CGExpr.cpp
Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=81602&r1=81601&r2=81602&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Fri Sep 11 21:44:18 2009
@@ -227,11 +227,9 @@
NoteForHelper[helpersize].flag = BLOCK_FIELD_IS_BYREF |
// FIXME: Someone double check this.
(VD->getType().isObjCGCWeak() ? BLOCK_FIELD_IS_WEAK : 0);
- 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;
Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=81602&r1=81601&r2=81602&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Fri Sep 11 21:44:18 2009
@@ -224,41 +224,76 @@
return Info.first;
QualType Ty = D->getType();
- uint64_t Align = getContext().getDeclAlignInBytes(D);
- (void) Align;
- const llvm::Type *LTy = ConvertType(Ty);
- bool needsCopyDispose = BlockRequiresCopying(Ty);
- std::vector<const llvm::Type *> Types(needsCopyDispose*2+5);
- const llvm::PointerType *PtrToInt8Ty
- = llvm::PointerType::getUnqual(llvm::Type::getInt8Ty(VMContext));
+ std::vector<const llvm::Type *> Types;
+ const llvm::PointerType *Int8PtrTy
+ = llvm::PointerType::getUnqual(llvm::Type::getInt8Ty(VMContext));
+
llvm::PATypeHolder ByRefTypeHolder = llvm::OpaqueType::get(VMContext);
- Types[0] = PtrToInt8Ty;
- Types[1] = llvm::PointerType::getUnqual(ByRefTypeHolder);
- Types[2] = llvm::Type::getInt32Ty(VMContext);
- Types[3] = llvm::Type::getInt32Ty(VMContext);
- if (needsCopyDispose) {
- Types[4] = PtrToInt8Ty;
- Types[5] = PtrToInt8Ty;
- }
- // FIXME: Align this on at least an Align boundary, assert if we can't.
- assert((Align <= unsigned(Target.getPointerAlign(0))/8)
- && "Can't align more than pointer yet");
+ // void *__isa;
+ Types.push_back(Int8PtrTy);
- unsigned FieldNumber = needsCopyDispose*2 + 4;
+ // void *__forwarding;
+ Types.push_back(llvm::PointerType::getUnqual(ByRefTypeHolder));
- Types[FieldNumber] = LTy;
+ // int32_t __flags;
+ Types.push_back(llvm::Type::getInt32Ty(VMContext));
+
+ // int32_t __size;
+ Types.push_back(llvm::Type::getInt32Ty(VMContext));
+
+ bool HasCopyAndDispose = BlockRequiresCopying(Ty);
+ if (HasCopyAndDispose) {
+ /// void *__copy_helper;
+ Types.push_back(Int8PtrTy);
+
+ /// void *__destroy_helper;
+ Types.push_back(Int8PtrTy);
+ }
+
+ bool Packed = false;
+ unsigned Align = getContext().getDeclAlignInBytes(D);
+ if (Align > Target.getPointerAlign(0) / 8) {
+ // We have to insert padding.
+
+ // The struct above has 2 32-bit integers.
+ unsigned CurrentOffsetInBytes = 4 * 2;
+
+ // And either 2 or 4 pointers.
+ CurrentOffsetInBytes += (HasCopyAndDispose ? 4 : 2) *
+ CGM.getTargetData().getTypeAllocSize(Int8PtrTy);
+
+ // Align the offset.
+ unsigned AlignedOffsetInBytes =
+ llvm::RoundUpToAlignment(CurrentOffsetInBytes, Align);
+
+ unsigned NumPaddingBytes = AlignedOffsetInBytes - CurrentOffsetInBytes;
+ assert(NumPaddingBytes > 0 && "Can't append any padding!");
+
+ const llvm::Type *Ty = llvm::Type::getInt8Ty(VMContext);
+ if (NumPaddingBytes > 1)
+ Ty = llvm::ArrayType::get(Ty, NumPaddingBytes);
+
+ Types.push_back(Ty);
+
+ // We want a packed struct.
+ Packed = true;
+ }
+
+ // T x;
+ Types.push_back(ConvertType(Ty));
- const llvm::Type *T = llvm::StructType::get(VMContext, Types, false);
+ const llvm::Type *T = llvm::StructType::get(VMContext, Types, Packed);
cast<llvm::OpaqueType>(ByRefTypeHolder.get())->refineAbstractTypeTo(T);
CGM.getModule().addTypeName("struct.__block_byref_" + D->getNameAsString(),
ByRefTypeHolder.get());
Info.first = ByRefTypeHolder.get();
- Info.second = FieldNumber;
+
+ Info.second = Types.size() - 1;
return Info.first;
}
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=81602&r1=81601&r2=81602&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Fri Sep 11 21:44:18 2009
@@ -716,15 +716,10 @@
if (!NonGCable)
attr = getContext().getObjCGCAttrKind(E->getType());
if (VD->hasAttr<BlocksAttr>()) {
- bool needsCopyDispose = BlockRequiresCopying(VD->getType());
- const llvm::Type *PtrStructTy = V->getType();
- const llvm::Type *Ty = PtrStructTy;
- Ty = llvm::PointerType::get(Ty, 0);
V = Builder.CreateStructGEP(V, 1, "forwarding");
- V = Builder.CreateBitCast(V, Ty);
V = Builder.CreateLoad(V, false);
- V = Builder.CreateBitCast(V, PtrStructTy);
- V = Builder.CreateStructGEP(V, needsCopyDispose*2 + 4, "x");
+ V = Builder.CreateStructGEP(V, getByRefValueLLVMField(VD),
+ VD->getNameAsString());
}
if (VD->getType()->isReferenceType())
V = Builder.CreateLoad(V, "tmp");
Added: cfe/trunk/test/CodeGen/blocks-aligned-byref-variable.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/blocks-aligned-byref-variable.c?rev=81602&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/blocks-aligned-byref-variable.c (added)
+++ cfe/trunk/test/CodeGen/blocks-aligned-byref-variable.c Fri Sep 11 21:44:18 2009
@@ -0,0 +1,11 @@
+// RUN: clang-cc -emit-llvm -o -
+typedef int __attribute__((aligned(32))) ai;
+
+void f() {
+ __block ai a = 10;
+
+ ^{
+ a = 20;
+ }();
+}
+
More information about the cfe-commits
mailing list