diff options
author | Anders Carlsson <andersca@mac.com> | 2011-03-20 19:51:13 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2011-03-20 19:51:13 +0000 |
commit | 1f7c7ba380cf411fd02a070822c439fadac91ce6 (patch) | |
tree | f909e203f1402fdf9a7c492d5e2a87a18bf381e9 /lib/Transforms | |
parent | 2dc455a366e26d8c1085ef617651232304ee097e (diff) | |
download | external_llvm-1f7c7ba380cf411fd02a070822c439fadac91ce6.zip external_llvm-1f7c7ba380cf411fd02a070822c439fadac91ce6.tar.gz external_llvm-1f7c7ba380cf411fd02a070822c439fadac91ce6.tar.bz2 |
Address comments from Frits van Bommel.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127974 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/IPO/GlobalOpt.cpp | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index b595d4c..12753cd 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -2706,9 +2706,10 @@ static Function *FindCXAAtExit(Module &M) { const FunctionType *FTy = Fn->getFunctionType(); - // Checking that the function has the right number of parameters and that they - // all have pointer types should be enough. - if (FTy->getNumParams() != 3 || + // Checking that the function has the right return type, the right number of + // parameters and that they all have pointer types should be enough. + if (!FTy->getReturnType()->isIntegerTy() || + FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() || !FTy->getParamType(1)->isPointerTy() || !FTy->getParamType(2)->isPointerTy()) @@ -2723,8 +2724,10 @@ static Function *FindCXAAtExit(Module &M) { /// the code so we only look for a function with a single basic block, where /// the only allowed instructions are 'ret' or 'call' to empty C++ dtor. static bool cxxDtorIsEmpty(const Function& Fn) { - if (Fn.empty()) - return true; + // FIXME: We could eliminate C++ destructors if they're readonly/readnone and + // unwind, but that doesn't seem worth doing. + if (Fn.isDeclaration()) + return false; if (++Fn.begin() != Fn.end()) return false; @@ -2738,6 +2741,10 @@ static bool cxxDtorIsEmpty(const Function& Fn) { if (!CalledFn) return false; + // Don't treat recursive functions as empty. + if (CalledFn == &Fn) + return false; + if (!cxxDtorIsEmpty(*CalledFn)) return false; } else if (isa<ReturnInst>(*I)) @@ -2769,7 +2776,7 @@ bool GlobalOpt::OptimizeEmptyGlobalCXXDtors(Function *CXAAtExitFn) { for (Function::use_iterator I = CXAAtExitFn->use_begin(), E = CXAAtExitFn->use_end(); I != E;) { CallSite CS(*I++); - if (!CS.getInstruction()) + if (!CS) continue; Function *DtorFn = @@ -2781,7 +2788,9 @@ bool GlobalOpt::OptimizeEmptyGlobalCXXDtors(Function *CXAAtExitFn) { continue; // Just remove the call. - CS.getInstruction()->eraseFromParent(); + CS->replaceAllUsesWith(Constant::getNullValue(CS.getType())); + CS->eraseFromParent(); + ++NumCXXDtorsRemoved; Changed |= true; |