summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGExprCXX.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-07-13 06:10:41 +0000
committerJohn McCall <rjmccall@apple.com>2011-07-13 06:10:41 +0000
commitf677a8e99eb93f078bfafe0792f5ae3e98885d8d (patch)
tree61e1b65bc6359e2bffd71ebe4a3c214df534e22d /clang/lib/CodeGen/CGExprCXX.cpp
parent46ca3272e48cac7e6afbf08ee1f320723eaf7632 (diff)
downloadbcm5719-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.cpp42
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))) {
OpenPOWER on IntegriCloud