diff options
author | Stephen Lin <stephenwlin@gmail.com> | 2013-06-18 17:00:49 +0000 |
---|---|---|
committer | Stephen Lin <stephenwlin@gmail.com> | 2013-06-18 17:00:49 +0000 |
commit | a637fb8ccdecd5b0a1171f262b48d62efe9452bd (patch) | |
tree | eb3bc6fd16bde72af833d25a71becd14980e2093 /clang/lib/CodeGen/CGCall.cpp | |
parent | c724765d528eb6bc22dc12774b98dedf2aba1491 (diff) | |
download | bcm5719-llvm-a637fb8ccdecd5b0a1171f262b48d62efe9452bd.tar.gz bcm5719-llvm-a637fb8ccdecd5b0a1171f262b48d62efe9452bd.zip |
CodeGen: Have 'this'-returning constructors and destructors to take advantage of the new backend 'returned' attribute.
The backend will now use the generic 'returned' attribute to form tail calls where possible, as well as avoid save-restores of 'this' in some cases (specifically the cases that matter for the ARM C++ ABI).
This patch also reverts a prior front-end only partial implementation of these optimizations, since it's no longer required.
llvm-svn: 184205
Diffstat (limited to 'clang/lib/CodeGen/CGCall.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 35 |
1 files changed, 8 insertions, 27 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 80446393d5b..f74ae391205 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -200,7 +200,10 @@ CodeGenTypes::arrangeCXXConstructorDeclaration(const CXXConstructorDecl *D, CXXCtorType ctorKind) { SmallVector<CanQualType, 16> argTypes; argTypes.push_back(GetThisType(Context, D->getParent())); - CanQualType resultType = Context.VoidTy; + + GlobalDecl GD(D, ctorKind); + CanQualType resultType = + TheCXXABI.HasThisReturn(GD) ? argTypes.front() : Context.VoidTy; TheCXXABI.BuildConstructorSignature(D, ctorKind, resultType, argTypes); @@ -225,7 +228,10 @@ CodeGenTypes::arrangeCXXDestructor(const CXXDestructorDecl *D, CXXDtorType dtorKind) { SmallVector<CanQualType, 2> argTypes; argTypes.push_back(GetThisType(Context, D->getParent())); - CanQualType resultType = Context.VoidTy; + + GlobalDecl GD(D, dtorKind); + CanQualType resultType = + TheCXXABI.HasThisReturn(GD) ? argTypes.front() : Context.VoidTy; TheCXXABI.BuildDestructorSignature(D, dtorKind, resultType, argTypes); @@ -1633,18 +1639,6 @@ static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) { return store; } -/// Check whether 'this' argument of a callsite matches 'this' of the caller. -static bool checkThisPointer(llvm::Value *ThisArg, llvm::Value *This) { - if (ThisArg == This) - return true; - // Check whether ThisArg is a bitcast of This. - llvm::BitCastInst *Bitcast; - if ((Bitcast = dyn_cast<llvm::BitCastInst>(ThisArg)) && - Bitcast->getOperand(0) == This) - return true; - return false; -} - void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI, bool EmitRetDbgLoc) { // Functions with no result always return void. @@ -1741,19 +1735,6 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI, llvm_unreachable("Invalid ABI kind for return argument"); } - // If this function returns 'this', the last instruction is a CallInst - // that returns 'this', and 'this' argument of the CallInst points to - // the same object as CXXThisValue, use the return value from the CallInst. - // We will not need to keep 'this' alive through the callsite. It also enables - // optimizations in the backend, such as tail call optimization. - if (CalleeWithThisReturn && CGM.getCXXABI().HasThisReturn(CurGD)) { - llvm::BasicBlock *IP = Builder.GetInsertBlock(); - llvm::CallInst *Callsite; - if (!IP->empty() && (Callsite = dyn_cast<llvm::CallInst>(&IP->back())) && - Callsite->getCalledFunction() == CalleeWithThisReturn && - checkThisPointer(Callsite->getOperand(0), CXXThisValue)) - RV = Builder.CreateBitCast(Callsite, RetAI.getCoerceToType()); - } llvm::Instruction *Ret = RV ? Builder.CreateRet(RV) : Builder.CreateRetVoid(); if (!RetDbgLoc.isUnknown()) Ret->setDebugLoc(RetDbgLoc); |