4 ms·
Induction detection is relatively simple in LLVM IR. The first thing to remember is that the compiler doesn't work on the same source code that the human does;
by jcranmer 5y ago
Induction detection is relatively simple in LLVM IR. The first thing to remember is that the compiler doesn't work on the same source code that the human does; it works on a different representation. The canonical loop structure would look something like this:
loop.preheader:
; This is the block that executes before the loop does.
br label %loop.body;
loop.body:
%i = phi i32 [0, %loop.preheader], [%i.next, %loop.body]
%val = phi i1 [0, %loop.preheader], [%val.next, %loop.body]
%val.next = xor i1 %val, -1
%i.next = add i32 %i, 1
%cmp = icmp slt i32 %i, %N
br i1 %cmp, %loop.exit, %loop.body
loop.exit:
; After the loop is done
Because of how phis work, in constructing this form, we immediately realize how to describe a value either in terms of its value in the first iteration (this is the value it takes coming from the preheader), or in terms solely of its value in the previous iteration. In other words, %val.next = f(%val) for some function f, which we can easily identify in the source code.
Now, if we can compute the repeated composition of f easily, we can replace the recurrence in the loop with repeated composition. Repeated addition of the same value is multiplication, and repeated multiplication of the same value is exponentiation--that's two very easy examples to do so. We recognize that there is no use of the value except of its final occurrence, and so instead of doing the loop, we can generate the composition itself. Thus, after N iterations of the loop, we can conclude that %val.next = f^N(0), and if we can identify the loop iteration count (that's %N in this case), we can simply write out f^N instead of having to compute every individual value.
- salawat 5y agoSo if I'm understanding this, this only works for loops with a finite number of iterations knowable at compile time, right?
- jcranmer 5y agoThe number of iterations must be knowable, yes. It doesn't need to be known as a direct constant value, but it must be computable as a symbolic value as some kind (say, an argument to the function, maybe plus or minus a constant). I haven't looked at the exact criteria in this transformation, but it's very likely that there are also a couple of constraints on how precisely the loop is structured.
- dw-im-here 5y agoCorrect, if you don't ensure the necessary preconditions are met you quickly run into undecidable problems.
- rocqua 5y agoHow does LLVM know to simplify f^N ? I've seen LLVM do the same optimization for triangular and pyramidal numbers. Is there a list of hardcoded functions it can handle? Does it try a specific algorithm to find the direct formula?