I want to write a pass for adding a function call in for
loop.
Let's assume the original source code is below.
for (int i=0; i<10; ++i)
{
printf("%d\n", i);
}
I want to make pass like changing the upper source code to below. (Not mean that changing the source code, but IR code in real.)
for (int i=0; i<10; ++i)
{
EXTERNALFUNC(i); // function call for external function
// and args is induction variable.
printf("%d\n", i);
}
I know about usage of getOrInsertFunction
method but have no idea about
If you run clang -emit-llvm
on that source you'll notice that the loop body starts with precisely one phi node. (Well, at least it ought to do that, I haven't bothered to check.)
Some loops don't have induction variables. But the ones that do will have a phi node and some sort of increase, and you can identify those once you've found the loop.
To find loops, you can make a LoopInfo, or if you're doing this in a pass, call FAM.getResult<LoopAnalysis>(F);
to get the LoopInfo your pass manager has made. For each loop found by LoopInfo, see if it's one you can analyse and do the right thing if it is, and if it isn't. The Loop's header must contain a phi, one of the incoming blocks must dominate the header, another must be in the loop, and the value in the loop must be an arithmetic operation that uses the phi. Like this:
scan: ; preds = %scan, %notnull
%previous = phi i32 [ -1, %notnull ], [ %current, %scan ]
%current = add i32 %previous, 1
…
br i1 %found, label %scan, label %test
If a loop doesn't have anything like this, it may be e.g. while(true){…}
.
BasicBlock::phis() tells you about its phi nodes, and PHINode::users() returns a list of things that use it. In the example above, %current
is an arithmethic operation, is one of the users of %previous
, and%previous
' getIncomingValue(1)
returns %current
too.