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 | 6a35b40250735a50efe66c88414cdd3b79185019 (patch) | |
tree | 85715b813e7c1a087961d5f6fc115641ef431279 /lib/Transforms/Scalar/TailRecursionElimination.cpp | |
parent | 849832c0fb47f4e111840e0031b9129d41ffb389 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73752 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/TailRecursionElimination.cpp')
-rw-r--r-- | lib/Transforms/Scalar/TailRecursionElimination.cpp | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/lib/Transforms/Scalar/TailRecursionElimination.cpp b/lib/Transforms/Scalar/TailRecursionElimination.cpp index 682d069923..34ee57c9b9 100644 --- a/lib/Transforms/Scalar/TailRecursionElimination.cpp +++ b/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 |