[llvm-commits] [llvm] r108056 - /llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp
Nick Lewycky
nicholas at mxc.ca
Sat Jul 10 13:47:03 PDT 2010
Duncan Sands wrote:
> Author: baldrick
> Date: Sat Jul 10 15:31:42 2010
> New Revision: 108056
>
> URL: http://llvm.org/viewvc/llvm-project?rev=108056&view=rev
> Log:
> The accumulator tail recursion transform claims to work for any associative
> operation, but the way it's implemented requires the operation to also be
> commutative. So add a check for commutativity (and tweak the corresponding
> comments). This makes no difference in practice since every associative
> LLVM instruction is also commutative!
Which leads to the question, how did you notice this? :)
Here's an example to show the need
> for commutativity: the accum_recursion.ll testcase calculates the factorial
> function. Before the transformation the result of a call is
> ((((1*1)*2)*3)...)*x
> while afterwards it is
> (((1*x)*(x-1))...*2)*1
> which clearly requires both associativity and commutativity of * to be equal
> to the original.
>
> Modified:
> llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp
>
> Modified: llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp?rev=108056&r1=108055&r2=108056&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp Sat Jul 10 15:31:42 2010
> @@ -16,9 +16,9 @@
> // transformation from taking place, though currently the analysis cannot
> // support moving any really useful instructions (only dead ones).
> // 2. This pass transforms functions that are prevented from being tail
> -// recursive by an associative expression to use an accumulator variable,
> -// thus compiling the typical naive factorial or 'fib' implementation into
> -// efficient code.
> +// recursive by an associative and commutative expression to use an
> +// accumulator variable, thus compiling the typical naive factorial or
> +// 'fib' implementation into efficient code.
> // 3. TRE is performed if the function returns void, if the return
> // returns the result returned by the call, or if the function returns a
> // run-time constant on all exits from the function. It is possible, though
> @@ -302,9 +302,9 @@
> ///
> Value *TailCallElim::CanTransformAccumulatorRecursion(Instruction *I,
> CallInst *CI) {
> - if (!I->isAssociative()) return 0;
> + if (!I->isAssociative() || !I->isCommutative()) return 0;
> assert(I->getNumOperands() == 2&&
> - "Associative operations should have 2 args!");
> + "Associative/commutative operations should have 2 args!");
>
> // Exactly one operand should be the result of the call instruction...
> if ((I->getOperand(0) == CI&& I->getOperand(1) == CI) ||
> @@ -369,11 +369,11 @@
> return false;
> }
>
> - // If we are introducing accumulator recursion to eliminate associative
> - // operations after the call instruction, this variable contains the initial
> - // value for the accumulator. If this value is set, we actually perform
> - // accumulator recursion elimination instead of simple tail recursion
> - // elimination.
> + // If we are introducing accumulator recursion to eliminate operations after
> + // the call instruction that are both associative and commutative, the initial
> + // value for the accumulator is placed in this variable. If this value is set
> + // then we actually perform accumulator recursion elimination instead of
> + // simple tail recursion elimination.
> Value *AccumulatorRecursionEliminationInitVal = 0;
> Instruction *AccumulatorRecursionInstr = 0;
>
> @@ -384,9 +384,9 @@
> for (BBI = CI, ++BBI;&*BBI != Ret; ++BBI)
> if (!CanMoveAboveCall(BBI, CI)) {
> // If we can't move the instruction above the call, it might be because it
> - // is an associative operation that could be tranformed using accumulator
> - // recursion elimination. Check to see if this is the case, and if so,
> - // remember the initial accumulator value for later.
> + // is an associative and commutative operation that could be tranformed
> + // using accumulator recursion elimination. Check to see if this is the
> + // case, and if so, remember the initial accumulator value for later.
> if ((AccumulatorRecursionEliminationInitVal =
> CanTransformAccumulatorRecursion(BBI, CI))) {
> // Yes, this is accumulator recursion. Remember which instruction
> @@ -483,7 +483,7 @@
> }
>
> // Add an incoming argument for the current block, which is computed by our
> - // associative accumulator instruction.
> + // associative and commutative accumulator instruction.
> AccPN->addIncoming(AccRecInstr, BB);
>
> // Next, rewrite the accumulator recursion instruction so that it does not
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
More information about the llvm-commits
mailing list