Convert if/else to a switch. NFC.

llvm-svn: 339613
This commit is contained in:
Akira Hatanaka 2018-08-13 20:59:57 +00:00
parent 28a42c7706
commit 4a6f190e19
1 changed files with 49 additions and 41 deletions

View File

@ -1874,57 +1874,65 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {
Address srcField = Builder.CreateStructGEP(src, index, capture.getOffset()); Address srcField = Builder.CreateStructGEP(src, index, capture.getOffset());
Address dstField = Builder.CreateStructGEP(dst, index, capture.getOffset()); Address dstField = Builder.CreateStructGEP(dst, index, capture.getOffset());
// If there's an explicit copy expression, we do that. switch (CopiedCapture.Kind) {
if (CI.getCopyExpr()) { case BlockCaptureEntityKind::CXXRecord:
assert(CopiedCapture.Kind == BlockCaptureEntityKind::CXXRecord); // If there's an explicit copy expression, we do that.
assert(CI.getCopyExpr() && "copy expression for variable is missing");
EmitSynthesizedCXXCopyCtor(dstField, srcField, CI.getCopyExpr()); EmitSynthesizedCXXCopyCtor(dstField, srcField, CI.getCopyExpr());
} else if (CopiedCapture.Kind == BlockCaptureEntityKind::ARCWeak) { break;
case BlockCaptureEntityKind::ARCWeak:
EmitARCCopyWeak(dstField, srcField); EmitARCCopyWeak(dstField, srcField);
// If this is a C struct that requires non-trivial copy construction, emit a break;
// call to its copy constructor. case BlockCaptureEntityKind::NonTrivialCStruct: {
} else if (CopiedCapture.Kind == // If this is a C struct that requires non-trivial copy construction,
BlockCaptureEntityKind::NonTrivialCStruct) { // emit a call to its copy constructor.
QualType varType = CI.getVariable()->getType(); QualType varType = CI.getVariable()->getType();
callCStructCopyConstructor(MakeAddrLValue(dstField, varType), callCStructCopyConstructor(MakeAddrLValue(dstField, varType),
MakeAddrLValue(srcField, varType)); MakeAddrLValue(srcField, varType));
} else { break;
}
case BlockCaptureEntityKind::ARCStrong: {
llvm::Value *srcValue = Builder.CreateLoad(srcField, "blockcopy.src"); llvm::Value *srcValue = Builder.CreateLoad(srcField, "blockcopy.src");
if (CopiedCapture.Kind == BlockCaptureEntityKind::ARCStrong) { // At -O0, store null into the destination field (so that the
// At -O0, store null into the destination field (so that the // storeStrong doesn't over-release) and then call storeStrong.
// storeStrong doesn't over-release) and then call storeStrong. // This is a workaround to not having an initStrong call.
// This is a workaround to not having an initStrong call. if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
if (CGM.getCodeGenOpts().OptimizationLevel == 0) { auto *ty = cast<llvm::PointerType>(srcValue->getType());
auto *ty = cast<llvm::PointerType>(srcValue->getType()); llvm::Value *null = llvm::ConstantPointerNull::get(ty);
llvm::Value *null = llvm::ConstantPointerNull::get(ty); Builder.CreateStore(null, dstField);
Builder.CreateStore(null, dstField); EmitARCStoreStrongCall(dstField, srcValue, true);
EmitARCStoreStrongCall(dstField, srcValue, true);
// With optimization enabled, take advantage of the fact that // With optimization enabled, take advantage of the fact that
// the blocks runtime guarantees a memcpy of the block data, and // the blocks runtime guarantees a memcpy of the block data, and
// just emit a retain of the src field. // just emit a retain of the src field.
} else {
EmitARCRetainNonBlock(srcValue);
// Unless EH cleanup is required, we don't need this anymore, so kill
// it. It's not quite worth the annoyance to avoid creating it in the
// first place.
if (!needsEHCleanup(captureType.isDestructedType()))
cast<llvm::Instruction>(dstField.getPointer())->eraseFromParent();
}
} else { } else {
assert(CopiedCapture.Kind == BlockCaptureEntityKind::BlockObject); EmitARCRetainNonBlock(srcValue);
srcValue = Builder.CreateBitCast(srcValue, VoidPtrTy);
llvm::Value *dstAddr =
Builder.CreateBitCast(dstField.getPointer(), VoidPtrTy);
llvm::Value *args[] = {
dstAddr, srcValue, llvm::ConstantInt::get(Int32Ty, flags.getBitMask())
};
if (CI.isByRef() && C.getBlockVarCopyInit(CI.getVariable()).canThrow()) // Unless EH cleanup is required, we don't need this anymore, so kill
EmitRuntimeCallOrInvoke(CGM.getBlockObjectAssign(), args); // it. It's not quite worth the annoyance to avoid creating it in the
else // first place.
EmitNounwindRuntimeCall(CGM.getBlockObjectAssign(), args); if (!needsEHCleanup(captureType.isDestructedType()))
cast<llvm::Instruction>(dstField.getPointer())->eraseFromParent();
} }
break;
}
case BlockCaptureEntityKind::BlockObject: {
llvm::Value *srcValue = Builder.CreateLoad(srcField, "blockcopy.src");
srcValue = Builder.CreateBitCast(srcValue, VoidPtrTy);
llvm::Value *dstAddr =
Builder.CreateBitCast(dstField.getPointer(), VoidPtrTy);
llvm::Value *args[] = {
dstAddr, srcValue, llvm::ConstantInt::get(Int32Ty, flags.getBitMask())
};
if (CI.isByRef() && C.getBlockVarCopyInit(CI.getVariable()).canThrow())
EmitRuntimeCallOrInvoke(CGM.getBlockObjectAssign(), args);
else
EmitNounwindRuntimeCall(CGM.getBlockObjectAssign(), args);
break;
}
case BlockCaptureEntityKind::None:
llvm_unreachable("unexpected BlockCaptureEntityKind");
} }
// Ensure that we destroy the copied object if an exception is thrown later // Ensure that we destroy the copied object if an exception is thrown later