llvm在循环中传递添加函数调用(归纳变量归纳args)

时间:2019-01-15 06:36:18

标签: llvm llvm-clang

我想写一个遍历,以在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方法的用法,但对

一无所知
  1. 找到循环和归纳变量
  2. 将函数调用放入函数内部
  3. 如果有很多循环,请将函数调用置于所有循环中。

1 个答案:

答案 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