[llvm-commits] Teach SCEV about {X,*,Y} recursions
Török Edwin
edwintorok at gmail.com
Sun Jun 1 02:13:04 PDT 2008
Chris Lattner wrote:
>
> On Apr 24, 2008, at 12:52 AM, Török Edwin wrote:
>
>> Chris Lattner wrote:
>>>
>>> On Apr 23, 2008, at 1:58 PM, Török Edwin wrote:
>>>
>>>> Hi,
>>>>
>>>> I have a patch that adds support for exponential recursions in loops.
>>>> This is useful in static analysis tools, and also for code
>>>> optimization.
>>>
>>> This is interesting, but a couple questions:
>>>
>>> 1) What sort of code does this really help with in practice? I'm a
>>> bit afraid of adding a bunch of complexity to SCEV analysis if it is
>>> unlikely to be useful for broad code. Do you see power sequences
>>> indexing arrays for example?
>>
>> It is useful if we can compute the loop exit value of a variable without
>> actually executing the loop (e.g. compute a^1980 w/o looping 1980
>> times), and thus the variable can
>> be moved out of the loop, and we can possibly delete the loop entirely.
>
> Yes, you're right. I guess my concern is that the current exit
> variable substitution, indvars, and LSR in general all need some sort
> of cost function to know whether it is profitable to rewrite
> something. I'm concerned that this change will cause code pessimization.
>
> For example, if indvars "recognizes" some code as an expression
> derived from an induction variable and rewrites it in terms of the
> canonical one, this often pessimizes code. This is currently by
> design though, as this is intended to simplify the code allowing other
> loop passes to analyze it efficiently. When LSR runs, it comes back
> and rewrites to inefficient code into the 'best' form for the target.
>
> The problem happens when indvars understands and rewrites something,
> but when LSR can't fix it.
I agree that code pessimization can occur: turning {1,*,2} into 2^indvar
inside the loop leads to worse code.
It looks like that handling {X,*,Y} is only beneficial if we can move
its computation outside the loop.
After running it on the benchmarks in llvm-test, I realised that its not
worth to handle {X,*,Y},
I think we could gain more performance from handling pow(X, <constant>).
I'll work on a patch for that.
>
>> If that variable is used for something else inside the loop (indexing an
>> array), then we get no advantage, we still need to loop N times, and
>> actually it is better to keep the original mul in this case.
>>
>> I see that powexpr got generated for at least these:
>> pifft, consumer-lame, telecomm-fft, voronoi, np, scimark2.
>>
>> I'll try to see if performance is actually improved in a real situation.
>
> Ok. What do these loops look like, out of curiousity?
There is no performance improvement, these are just
for(...;....;dual *= 2) {
... something that uses dual ...
}
In this case transforming dual *= 2 to {1,*,2} just complicates things.
>
>>> 2) instead of having SCEVExpander::visitPowExpr emit multiplies, it
>>> should emit a call to llvm.powi.
>>
>> I would need a powi that takes an integer argument as a base.
>> I don't want to introduce FP code where there wasn't any before. Also it
>> would currently force us to link the resulting code with -lm, right?
>> Should I add a powi that takes an integer base?
>
> Ah right. I think it would be interesting to make powi work with
> integers. The code generator could always expand it into inline code
> instead of calling libm if needed.
Ok.
> Alternatively, perhaps there is already a libgcc function that does this?
I didn't see any libgcc functions for integers, only for floats:
__powi[sdx]f2
>
>>> 3) It would be really nice to teach the code generator to lower
>>> llvm.powi nicer, particularly before something like this patch goes
>>> in. Our current lowering of powi is pretty naive.
>>
>> AFAICT it is just transformed into a libcall. Would you like me to move
>> the constant-power codegen code there?
>
> Yep, that's what I mean. Thanks Edwin,
Ok, I will do that, and also add a powi that takes only integers as
parameters.
Best regards,
--Edwin
More information about the llvm-commits
mailing list