diff options
author | John McCall <rjmccall@apple.com> | 2011-07-13 06:10:41 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-07-13 06:10:41 +0000 |
commit | f677a8e99eb93f078bfafe0792f5ae3e98885d8d (patch) | |
tree | 61e1b65bc6359e2bffd71ebe4a3c214df534e22d /clang/lib/CodeGen/CGExprCXX.cpp | |
parent | 46ca3272e48cac7e6afbf08ee1f320723eaf7632 (diff) | |
download | bcm5719-llvm-f677a8e99eb93f078bfafe0792f5ae3e98885d8d.tar.gz bcm5719-llvm-f677a8e99eb93f078bfafe0792f5ae3e98885d8d.zip |
Convert the standard default-construction loops to use phis and
partial destruction.
llvm-svn: 135033
Diffstat (limited to 'clang/lib/CodeGen/CGExprCXX.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExprCXX.cpp | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index 07997e43911..49aab66268c 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -379,19 +379,11 @@ CodeGenFunction::EmitCXXConstructExpr(const CXXConstructExpr *E, } } - const ConstantArrayType *Array - = getContext().getAsConstantArrayType(E->getType()); - if (Array) { - QualType BaseElementTy = getContext().getBaseElementType(Array); - const llvm::Type *BasePtr = ConvertType(BaseElementTy); - BasePtr = llvm::PointerType::getUnqual(BasePtr); - llvm::Value *BaseAddrPtr = - Builder.CreateBitCast(Dest.getAddr(), BasePtr); - - EmitCXXAggrConstructorCall(CD, Array, BaseAddrPtr, + if (const ConstantArrayType *arrayType + = getContext().getAsConstantArrayType(E->getType())) { + EmitCXXAggrConstructorCall(CD, arrayType, Dest.getAddr(), E->arg_begin(), E->arg_end()); - } - else { + } else { CXXCtorType Type = Ctor_Complete; bool ForVirtualBase = false; @@ -805,11 +797,37 @@ static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E, RequiresZeroInitialization = true; } + + // It's legal for NumElements to be zero, but + // EmitCXXAggrConstructorCall doesn't handle that, so we need to. + llvm::BranchInst *br = 0; + + // Optimize for a constant count. + llvm::ConstantInt *constantCount + = dyn_cast<llvm::ConstantInt>(NumElements); + if (constantCount) { + // Just skip out if the constant count is zero. + if (constantCount->isZero()) return; + + // Otherwise, emit the check. + } else { + llvm::BasicBlock *loopBB = CGF.createBasicBlock("new.ctorloop"); + llvm::Value *iszero = CGF.Builder.CreateIsNull(NumElements, "isempty"); + br = CGF.Builder.CreateCondBr(iszero, loopBB, loopBB); + CGF.EmitBlock(loopBB); + } CGF.EmitCXXAggrConstructorCall(Ctor, NumElements, NewPtr, E->constructor_arg_begin(), E->constructor_arg_end(), RequiresZeroInitialization); + + // Patch the earlier check to skip over the loop. + if (br) { + assert(CGF.Builder.GetInsertBlock()->empty()); + br->setSuccessor(0, CGF.Builder.GetInsertBlock()); + } + return; } else if (E->getNumConstructorArgs() == 1 && isa<ImplicitValueInitExpr>(E->getConstructorArg(0))) { |