[LLVMdev] RFC: Recursive inlining
Jeremy Lakeman
Jeremy.Lakeman at gmail.com
Thu Feb 5 05:56:49 PST 2015
Thinking about this some more I realise I could explain this more clearly.
I think we can manipulate the bitcode fairly easily, and in the same way
for all recursive functions.
before;
void func(%arg1, ...) {
entry:
// ...
terminate:
// ...
ret;
recursive_call:
// ...
call func(%arg1_tmp, ...)
// ...
end:
// ...
ret;
}
after;
void func(%arg1_top, ...) {
entry:
push state_end
br recurse;
recurse:
%arg1 = phi %arg1_top, %arg1_tmp, ....
// ...
terminate:
// ...
br state_ret;
recursive_call:
// ...
push live values
push state 1
br recurse;
state1:
pop live values
// ...
end:
// ...
br state_ret;
state_ret:
%state = pop state
switch %state{
case state_end: br finish;
case 1: br state1;
.... other states ...
}
finish:
ret;
}
On Thu, Feb 5, 2015 at 10:53 PM, Jeremy Lakeman <Jeremy.Lakeman at gmail.com>
wrote:
>
>
> On Thu, Feb 5, 2015 at 9:06 PM, James Molloy <james at jamesmolloy.co.uk>
> wrote:
>
>> Now what about a more complex case, like in the FFT butterfly algorithm:
>>
>> void ex4(i) {
>> if (is_base(i)) {
>> f(i); return;
>> }
>> g(i);
>> ex4(i / 2);
>> ex4(i / 2 + 1);
>> h(i);
>> }
>>
>>
>>
> This sounds like a very similar process to transforming a C# IEnumerable's
> "yield" into a state machine. There might be some relevant literature in
> this area.
> So essentially we just need to;
> - replace call's with a stack push and jump to entry block
> - replace return's with a stack pop and jump to the state following the
> call or return.
> And try to avoid pushing any invariant values.
>
> Something along these lines?
>
> struct stack{
> state;
> i;
> }
>
> void ex4(i) {
> entry:
> struct stack *stack = intrinsic.stackptr() // ??
> goto state_0;
>
> state_0:
> i0 = phi [i, i1, i2]
> stack0 = phi [stack, stack1, stack2]
> if (is_base(i)){
> f(i);
> goto state_ret;
> }
> g(i);
> i1 = i0 / 2;
> stack0->state=1;
> stack0->i = i0;
> stack1 = stack0 + 1;
> goto state_0;
>
> state_1:
> i2 = i3 / 2 + 1;
> stack0->state=2;
> stack0->i = i;
> stack2 = stack0 + 1;
> goto state_0;
>
> state_2:
> h(i3);
> goto state_ret;
>
> state_ret:
> stack3 = phi [stack0, stack3]
> if( stack3 == stack ) return;
> stack4 = stack3 - 1;
> i2 = stack4->i;
> switch(stack4->state){
> case 1: goto state_1;
> case 2: goto state_2;
> default: unreachable;
> }
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150206/8e048daa/attachment.html>
More information about the llvm-dev
mailing list