summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CGBlocks.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2013-06-10 20:45:12 +0000
committerdim <dim@FreeBSD.org>2013-06-10 20:45:12 +0000
commitea266cad53e3d49771fa38103913d3ec7a166694 (patch)
tree8f7776b7310bebaf415ac5b69e46e9f928c37144 /lib/CodeGen/CGBlocks.cpp
parentc72c57c9e9b69944e3e009cd5e209634839581d3 (diff)
downloadFreeBSD-src-ea266cad53e3d49771fa38103913d3ec7a166694.zip
FreeBSD-src-ea266cad53e3d49771fa38103913d3ec7a166694.tar.gz
Vendor import of clang tags/RELEASE_33/final r183502 (effectively, 3.3
release): http://llvm.org/svn/llvm-project/cfe/tags/RELEASE_33/final@183502
Diffstat (limited to 'lib/CodeGen/CGBlocks.cpp')
-rw-r--r--lib/CodeGen/CGBlocks.cpp70
1 files changed, 35 insertions, 35 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index 227ee2d..ded019e 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -695,8 +695,8 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
bool isLambdaConv = blockInfo.getBlockDecl()->isConversionFromLambda();
llvm::Constant *blockFn
= CodeGenFunction(CGM, true).GenerateBlockFunction(CurGD, blockInfo,
- CurFuncDecl, LocalDeclMap,
- isLambdaConv);
+ LocalDeclMap,
+ isLambdaConv);
blockFn = llvm::ConstantExpr::getBitCast(blockFn, VoidPtrTy);
// If there is nothing to capture, we can emit this as a global block.
@@ -753,6 +753,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
if (capture.isConstant()) continue;
QualType type = variable->getType();
+ CharUnits align = getContext().getDeclAlign(variable);
// This will be a [[type]]*, except that a byref entry will just be
// an i8**.
@@ -796,21 +797,21 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
if (ci->isByRef()) {
// Get a void* that points to the byref struct.
if (ci->isNested())
- src = Builder.CreateLoad(src, "byref.capture");
+ src = Builder.CreateAlignedLoad(src, align.getQuantity(),
+ "byref.capture");
else
src = Builder.CreateBitCast(src, VoidPtrTy);
// Write that void* into the capture field.
- Builder.CreateStore(src, blockField);
+ Builder.CreateAlignedStore(src, blockField, align.getQuantity());
// If we have a copy constructor, evaluate that into the block field.
} else if (const Expr *copyExpr = ci->getCopyExpr()) {
if (blockDecl->isConversionFromLambda()) {
// If we have a lambda conversion, emit the expression
// directly into the block instead.
- CharUnits Align = getContext().getTypeAlignInChars(type);
AggValueSlot Slot =
- AggValueSlot::forAddr(blockField, Align, Qualifiers(),
+ AggValueSlot::forAddr(blockField, align, Qualifiers(),
AggValueSlot::IsDestructed,
AggValueSlot::DoesNotNeedGCBarriers,
AggValueSlot::IsNotAliased);
@@ -821,7 +822,27 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
// If it's a reference variable, copy the reference into the block field.
} else if (type->isReferenceType()) {
- Builder.CreateStore(Builder.CreateLoad(src, "ref.val"), blockField);
+ llvm::Value *ref =
+ Builder.CreateAlignedLoad(src, align.getQuantity(), "ref.val");
+ Builder.CreateAlignedStore(ref, blockField, align.getQuantity());
+
+ // If this is an ARC __strong block-pointer variable, don't do a
+ // block copy.
+ //
+ // TODO: this can be generalized into the normal initialization logic:
+ // we should never need to do a block-copy when initializing a local
+ // variable, because the local variable's lifetime should be strictly
+ // contained within the stack block's.
+ } else if (type.getObjCLifetime() == Qualifiers::OCL_Strong &&
+ type->isBlockPointerType()) {
+ // Load the block and do a simple retain.
+ LValue srcLV = MakeAddrLValue(src, type, align);
+ llvm::Value *value = EmitLoadOfScalar(srcLV);
+ value = EmitARCRetainNonBlock(value);
+
+ // Do a primitive store to the block field.
+ LValue destLV = MakeAddrLValue(blockField, type, align);
+ EmitStoreOfScalar(value, destLV, /*init*/ true);
// Otherwise, fake up a POD copy into the block field.
} else {
@@ -839,8 +860,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
ImplicitCastExpr l2r(ImplicitCastExpr::OnStack, type, CK_LValueToRValue,
&declRef, VK_RValue);
EmitExprAsInit(&l2r, &blockFieldPseudoVar,
- MakeAddrLValue(blockField, type,
- getContext().getDeclAlign(variable)),
+ MakeAddrLValue(blockField, type, align),
/*captured by init*/ false);
}
@@ -1014,7 +1034,7 @@ CodeGenModule::GetAddrOfGlobalBlock(const BlockExpr *blockExpr,
llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap;
blockFn = CodeGenFunction(*this).GenerateBlockFunction(GlobalDecl(),
blockInfo,
- 0, LocalDeclMap,
+ LocalDeclMap,
false);
}
blockFn = llvm::ConstantExpr::getBitCast(blockFn, VoidPtrTy);
@@ -1068,7 +1088,6 @@ static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM,
llvm::Function *
CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,
const CGBlockInfo &blockInfo,
- const Decl *outerFnDecl,
const DeclMapTy &ldm,
bool IsLambdaConversionToBlock) {
const BlockDecl *blockDecl = blockInfo.getBlockDecl();
@@ -1128,7 +1147,6 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,
// Begin generating the function.
StartFunction(blockDecl, fnType->getResultType(), fn, fnInfo, args,
blockInfo.getBlockExpr()->getBody()->getLocStart());
- CurFuncDecl = outerFnDecl; // StartFunction sets this to blockDecl
// Okay. Undo some of what StartFunction did.
@@ -1149,11 +1167,9 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,
Alloca->setAlignment(Align);
// Set the DebugLocation to empty, so the store is recognized as a
// frame setup instruction by llvm::DwarfDebug::beginFunction().
- llvm::DebugLoc Empty;
- llvm::DebugLoc Loc = Builder.getCurrentDebugLocation();
- Builder.SetCurrentDebugLocation(Empty);
+ Builder.DisableDebugLocations();
Builder.CreateAlignedStore(BlockPointer, Alloca, Align);
- Builder.SetCurrentDebugLocation(Loc);
+ Builder.EnableDebugLocations();
BlockPointerDbgLoc = Alloca;
}
@@ -1166,23 +1182,6 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,
CXXThisValue = Builder.CreateLoad(addr, "this");
}
- // LoadObjCSelf() expects there to be an entry for 'self' in LocalDeclMap;
- // appease it.
- if (const ObjCMethodDecl *method
- = dyn_cast_or_null<ObjCMethodDecl>(CurFuncDecl)) {
- const VarDecl *self = method->getSelfDecl();
-
- // There might not be a capture for 'self', but if there is...
- if (blockInfo.Captures.count(self)) {
- const CGBlockInfo::Capture &capture = blockInfo.getCapture(self);
-
- llvm::Value *selfAddr = Builder.CreateStructGEP(BlockPointer,
- capture.getIndex(),
- "block.captured-self");
- LocalDeclMap[self] = selfAddr;
- }
- }
-
// Also force all the constant captures.
for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(),
ce = blockDecl->capture_end(); ci != ce; ++ci) {
@@ -1241,7 +1240,7 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,
}
// Recover location if it was changed in the above loop.
DI->EmitLocation(Builder,
- cast<CompoundStmt>(blockDecl->getBody())->getRBracLoc());
+ cast<CompoundStmt>(blockDecl->getBody())->getRBracLoc());
}
// And resume where we left off.
@@ -2062,7 +2061,8 @@ llvm::Type *CodeGenFunction::BuildByRefType(const VarDecl *D) {
bool Packed = false;
CharUnits Align = getContext().getDeclAlign(D);
- if (Align > getContext().toCharUnitsFromBits(Target.getPointerAlign(0))) {
+ if (Align >
+ getContext().toCharUnitsFromBits(getTarget().getPointerAlign(0))) {
// We have to insert padding.
// The struct above has 2 32-bit integers.
OpenPOWER on IntegriCloud