我想写一个遍历,以在for
循环中添加函数调用。
假定原始源代码在下面。
for (int i=0; i<10; ++i)
{
printf("%d\n", i);
}
我想通过,就像将上面的源代码更改为下面那样。 (这并不意味着更改 source 代码,而是真正地更改 IR 代码。)
for (int i=0; i<10; ++i)
{
EXTERNALFUNC(i); // function call for external function
// and args is induction variable.
printf("%d\n", i);
}
我知道getOrInsertFunction
方法的用法,但对
答案 0 :(得分:1)
如果在该源上运行clang -emit-llvm
,您会注意到循环体恰好从一个phi节点开始。 (嗯,至少它应该这样做,我没有费心检查。)
某些循环没有归纳变量。但是,这样做的人将有一个phi节点并进行某种程度的增加,一旦找到循环,便可以识别出它们。
要查找循环,可以创建一个LoopInfo,或者如果要通过循环,则调用FAM.getResult<LoopAnalysis>(F);
以获取pass manager制作的LoopInfo。对于LoopInfo找到的每个循环,请查看是否可以分析并进行正确的操作(如果不是)。循环的标头必须包含phi,incoming blocks中的一个必须控制标头,另一个必须在循环中,并且循环中的值必须是使用phi的算术运算。像这样:
scan: ; preds = %scan, %notnull
%previous = phi i32 [ -1, %notnull ], [ %current, %scan ]
%current = add i32 %previous, 1
…
br i1 %found, label %scan, label %test
如果循环中没有这样的内容,则可能是while(true){…}
。
BasicBlock::phis()告诉您有关其phi节点的信息,PHINode::users()返回使用它的事物的列表。在上面的示例中,%current
是一种算术运算,是%previous
的用户之一,并且%previous
'getIncomingValue(1)
也返回%current
。