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 | f80fcd00b3590626a6110fe5fbe9b5fd2a8be1ae (patch) | |
tree | 9090f3aa1b8170993671f2479436182b6ee9fc09 /lib/Transforms/Scalar/TailRecursionElimination.cpp | |
parent | bf992817f28bdab09fe1d1349561efb0c89fb0dd (diff) | |
download | llvm-f80fcd00b3590626a6110fe5fbe9b5fd2a8be1ae.tar.gz llvm-f80fcd00b3590626a6110fe5fbe9b5fd2a8be1ae.tar.bz2 llvm-f80fcd00b3590626a6110fe5fbe9b5fd2a8be1ae.tar.xz |
Improve tail call elimination to handle the switch statement.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86403 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/TailRecursionElimination.cpp')
-rw-r--r-- | lib/Transforms/Scalar/TailRecursionElimination.cpp | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/lib/Transforms/Scalar/TailRecursionElimination.cpp b/lib/Transforms/Scalar/TailRecursionElimination.cpp index e05991373a..4119cb9db4 100644 --- a/lib/Transforms/Scalar/TailRecursionElimination.cpp +++ b/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) |