diff options
| author | Nick Lewycky <nicholas@mxc.ca> | 2009-11-07 21:10:15 +0000 |
|---|---|---|
| committer | Nick Lewycky <nicholas@mxc.ca> | 2009-11-07 21:10:15 +0000 |
| commit | b9397262b7acf938f0958072a9765921ceead706 (patch) | |
| tree | e40c9594d107f3c293c2dff2c0da656d4536b87e /llvm/lib/Transforms/Scalar | |
| parent | d7aa9d8a636e1555b4706949f6eee4a867b0fa2b (diff) | |
| download | bcm5719-llvm-b9397262b7acf938f0958072a9765921ceead706.tar.gz bcm5719-llvm-b9397262b7acf938f0958072a9765921ceead706.zip | |
Improve tail call elimination to handle the switch statement.
llvm-svn: 86403
Diffstat (limited to 'llvm/lib/Transforms/Scalar')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp b/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp index e05991373a8..4119cb9db41 100644 --- a/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp +++ b/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp @@ -234,7 +234,7 @@ bool TailCallElim::CanMoveAboveCall(Instruction *I, CallInst *CI) { // We currently handle static constants and arguments that are not modified as // part of the recursion. // -static bool isDynamicConstant(Value *V, CallInst *CI) { +static bool isDynamicConstant(Value *V, CallInst *CI, ReturnInst *RI) { if (isa<Constant>(V)) return true; // Static constants are always dyn consts // Check to see if this is an immutable argument, if so, the value @@ -252,6 +252,15 @@ static bool isDynamicConstant(Value *V, CallInst *CI) { if (CI->getOperand(ArgNo+1) == Arg) return true; } + + // Switch cases are always constant integers. If the value is being switched + // on and the return is only reachable from one of its cases, it's + // effectively constant. + if (BasicBlock *UniquePred = RI->getParent()->getUniquePredecessor()) + if (SwitchInst *SI = dyn_cast<SwitchInst>(UniquePred->getTerminator())) + if (SI->getCondition() == V) + return SI->getDefaultDest() != RI->getParent(); + // Not a constant or immutable argument, we can't safely transform. return false; } @@ -273,7 +282,7 @@ static Value *getCommonReturnValue(ReturnInst *TheRI, CallInst *CI) { // evaluatable at the start of the initial invocation of the function, // instead of at the end of the evaluation. // - if (!isDynamicConstant(RetOp, CI)) + if (!isDynamicConstant(RetOp, CI, RI)) return 0; if (ReturnedValue && RetOp != ReturnedValue) |

