diff options
author | Chris Lattner <sabre@nondot.org> | 2009-06-19 04:22:16 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-06-19 04:22:16 +0000 |
commit | 5ca41978295cbf0d4f7f1851b15e217629d38919 (patch) | |
tree | 40e8be5fda1b317efe1e9af9c4ab777751857c80 /llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp | |
parent | 87a222c5c870b1352e4672b1072ba6ddf904ce16 (diff) | |
download | bcm5719-llvm-5ca41978295cbf0d4f7f1851b15e217629d38919.tar.gz bcm5719-llvm-5ca41978295cbf0d4f7f1851b15e217629d38919.zip |
Improve tail call elim to move loads above readonly calls
when it allows forming a tail call. Patch by Frits van
Bommel. This implements PR4323.
llvm-svn: 73752
Diffstat (limited to 'llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp b/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp index 682d069923e..34ee57c9b9d 100644 --- a/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp +++ b/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp @@ -52,6 +52,7 @@ #define DEBUG_TYPE "tailcallelim" #include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" @@ -201,8 +202,21 @@ bool TailCallElim::runOnFunction(Function &F) { bool TailCallElim::CanMoveAboveCall(Instruction *I, CallInst *CI) { // FIXME: We can move load/store/call/free instructions above the call if the // call does not mod/ref the memory location being processed. - if (I->mayHaveSideEffects() || isa<LoadInst>(I)) + if (I->mayHaveSideEffects()) // This also handles volatile loads. return false; + + if (LoadInst* L = dyn_cast<LoadInst>(I)) { + // Loads may always be moved above calls without side effects. + if (CI->mayHaveSideEffects()) { + // Non-volatile loads may be moved above a call with side effects if it + // does not write to memory and the load provably won't trap. + // FIXME: Writes to memory only matter if they may alias the pointer + // being loaded from. + if (CI->mayWriteToMemory() || + !isSafeToLoadUnconditionally(L->getPointerOperand(), L)) + return false; + } + } // Otherwise, if this is a side-effect free instruction, check to make sure // that it does not use the return value of the call. If it doesn't use the |