diff options
author | dim <dim@FreeBSD.org> | 2013-06-10 20:45:12 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2013-06-10 20:45:12 +0000 |
commit | ea266cad53e3d49771fa38103913d3ec7a166694 (patch) | |
tree | 8f7776b7310bebaf415ac5b69e46e9f928c37144 /lib/CodeGen/CGBlocks.cpp | |
parent | c72c57c9e9b69944e3e009cd5e209634839581d3 (diff) | |
download | FreeBSD-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.cpp | 70 |
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. |