diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-07-21 23:12:18 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-07-21 23:12:18 +0000 |
commit | 8d0dc31dcada7f8002022b02a1cee471494e530b (patch) | |
tree | 03cb4aaeb4dc0f66bb8fde6afa282a87c40d41fd /clang/lib/CodeGen/CGExprCXX.cpp | |
parent | 70523c79260864b64c95bb2b31746eacbf2e06bd (diff) | |
download | bcm5719-llvm-8d0dc31dcada7f8002022b02a1cee471494e530b.tar.gz bcm5719-llvm-8d0dc31dcada7f8002022b02a1cee471494e530b.zip |
Tighten up the set of operator new/operator delete calls we're permitted to
optimize, to follow the permissions granted in N3664. Under those rules, only
calls generated by new-expressions and delete-expressions are permitted to be
optimized, and direct calls to ::operator new and ::operator delete must be
treated as normal calls.
llvm-svn: 186799
Diffstat (limited to 'clang/lib/CodeGen/CGExprCXX.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExprCXX.cpp | 53 |
1 files changed, 37 insertions, 16 deletions
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index 672e86d0d8f..1520656c9b8 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -1002,6 +1002,38 @@ static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E, StoreAnyExprIntoOneUnit(CGF, Init, E->getAllocatedType(), NewPtr); } +/// Emit a call to an operator new or operator delete function, as implicitly +/// created by new-expressions and delete-expressions. +static RValue EmitNewDeleteCall(CodeGenFunction &CGF, + const FunctionDecl *Callee, + const FunctionProtoType *CalleeType, + const CallArgList &Args) { + llvm::Instruction *CallOrInvoke; + RValue RV = + CGF.EmitCall(CGF.CGM.getTypes().arrangeFreeFunctionCall(Args, CalleeType), + CGF.CGM.GetAddrOfFunction(Callee), ReturnValueSlot(), Args, + Callee, &CallOrInvoke); + + /// C++1y [expr.new]p10: + /// [In a new-expression,] an implementation is allowed to omit a call + /// to a replaceable global allocation function. + /// + /// We model such elidable calls with the 'builtin' attribute. + if (Callee->isReplaceableGlobalAllocationFunction()) { + // FIXME: Add addAttribute to CallSite. + if (llvm::CallInst *CI = dyn_cast<llvm::CallInst>(CallOrInvoke)) + CI->addAttribute(llvm::AttributeSet::FunctionIndex, + llvm::Attribute::Builtin); + else if (llvm::InvokeInst *II = dyn_cast<llvm::InvokeInst>(CallOrInvoke)) + II->addAttribute(llvm::AttributeSet::FunctionIndex, + llvm::Attribute::Builtin); + else + llvm_unreachable("unexpected kind of call instruction"); + } + + return RV; +} + namespace { /// A cleanup to call the given 'operator delete' function upon /// abnormal exit from a new expression. @@ -1051,9 +1083,7 @@ namespace { DeleteArgs.add(getPlacementArgs()[I], *AI++); // Call 'operator delete'. - CGF.EmitCall(CGF.CGM.getTypes().arrangeFreeFunctionCall(DeleteArgs, FPT), - CGF.CGM.GetAddrOfFunction(OperatorDelete), - ReturnValueSlot(), DeleteArgs, OperatorDelete); + EmitNewDeleteCall(CGF, OperatorDelete, FPT, DeleteArgs); } }; @@ -1112,9 +1142,7 @@ namespace { } // Call 'operator delete'. - CGF.EmitCall(CGF.CGM.getTypes().arrangeFreeFunctionCall(DeleteArgs, FPT), - CGF.CGM.GetAddrOfFunction(OperatorDelete), - ReturnValueSlot(), DeleteArgs, OperatorDelete); + EmitNewDeleteCall(CGF, OperatorDelete, FPT, DeleteArgs); } }; } @@ -1227,10 +1255,7 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { // TODO: kill any unnecessary computations done for the size // argument. } else { - RV = EmitCall(CGM.getTypes().arrangeFreeFunctionCall(allocatorArgs, - allocatorType), - CGM.GetAddrOfFunction(allocator), ReturnValueSlot(), - allocatorArgs, allocator); + RV = EmitNewDeleteCall(*this, allocator, allocatorType, allocatorArgs); } // Emit a null check on the allocation result if the allocation @@ -1350,9 +1375,7 @@ void CodeGenFunction::EmitDeleteCall(const FunctionDecl *DeleteFD, DeleteArgs.add(RValue::get(Size), SizeTy); // Emit the call to delete. - EmitCall(CGM.getTypes().arrangeFreeFunctionCall(DeleteArgs, DeleteFTy), - CGM.GetAddrOfFunction(DeleteFD), ReturnValueSlot(), - DeleteArgs, DeleteFD); + EmitNewDeleteCall(*this, DeleteFD, DeleteFTy, DeleteArgs); } namespace { @@ -1508,9 +1531,7 @@ namespace { } // Emit the call to delete. - CGF.EmitCall(CGF.getTypes().arrangeFreeFunctionCall(Args, DeleteFTy), - CGF.CGM.GetAddrOfFunction(OperatorDelete), - ReturnValueSlot(), Args, OperatorDelete); + EmitNewDeleteCall(CGF, OperatorDelete, DeleteFTy, Args); } }; } |