从LLVM IR中删除基本块中的第一条指令?

从LLVM IR中删除基本块中的第一条指令?,llvm,Llvm,我有以下LLVM IR文件 %1 = load i32* %i, align 4 %2 = load i32* %j, align 4 %3 = icmp sgt i32 %1, %2 br i1 %3, label %4, label %6 ; <label>:4 ; preds = %0 %5 = load i32* %i, align 4 store i32 %5, i32*

我有以下LLVM IR文件

  %1 = load i32* %i, align 4
  %2 = load i32* %j, align 4
  %3 = icmp sgt i32 %1, %2
  br i1 %3, label %4, label %6

; <label>:4                                       ; preds = %0
  %5 = load i32* %i, align 4
  store i32 %5, i32* %k, align 4
  br label %6

; <label>:6                                       ; preds = %5, %0
  ret i32 0
%1=加载i32*%i,对齐4
%2=负载i32*%j,对齐4
%3=icmp sgt i32%1,%2
br i1%3,标签%4,标签%6
; :4.preds=%0
%5=负载i32*%i,对齐4
存储i32%5,i32*%k,对齐4
br标签%6
; :6.preds=%5,%0
ret i32 0
在其中,我首先在%1中加载变量“I”,在%2中加载变量“j”,然后比较大于条件(I>j)。基于此,标签4或标签6存在分支。我的问题是变量“i”有两条加载指令,一条在第一个基本块中,另一条在第二个基本块中。这里我想删除第二个加载指令。 对于它,当我到达变量“I”的第二条加载指令时,我用第一条指令替换第二条指令的所有用法,然后删除当前指令,即第二条指令。这里我无法设置指令迭代器指针。我不想设置下一条指令(存储i32%5,i32*%k,对齐4)。还有别的办法吗?
如果您知道,请告诉我。

如果我理解正确,您只需删除一条指令并不断迭代代码即可。如果这是正确的,请从
deadInstelimation
过程(位于
lib/Transforms/Scalar/DCE.cpp
)中查看此示例:


有趣的是迭代器是如何递增的。
DI++
不是在
for
的最后一个子句中完成的,而是单独完成的,将当前
DI
分配给
Inst
。这样可以确保即使您删除
Inst
DI
已经指向下一条指令,因此循环将继续运行下一条指令。

我不确定是否理解您的问题。但我非常确定,后续的传球应该能够轻松地为你消除负担,所以我不会真的费心。如果您有令人信服的理由删除加载,请重申您的问题,因为我无法理解您的问题到底是什么。我的问题是,在删除第二条加载指令后,我想设置指令迭代器,以便在下一次迭代中它应该达到(存储i32%5,i32*%k,对齐4)因为在for循环中,我正在增加指令迭代器。为什么不在
inst->eraseFromParent()
之后立即再次调用
BB->begin()
来获得一个新的迭代器呢?非常感谢您的帮助,:)它工作正常。多么简单的解决方案!多亏了你的帮助。你所说的是正确的,而且它工作正常。我的问题解决了!,:-)我从CAFxX那里得到了一个解决方案。也感谢您的帮助。@damrudhard:只有在新指令是基本块中的第一条指令时,才可以将新迭代器设置为
BB->begin()
。否则,您将返回一些说明。如果你同意,那就没问题了。不过,我认为我的答案中显示的解决方案更一般。在另一种情况下,我将指令迭代器设置为上一条指令,以便在下一次迭代中,它将指向删除指令之后的指令。
virtual bool runOnBasicBlock(BasicBlock &BB) {
  bool Changed = false;
  for (BasicBlock::iterator DI = BB.begin(); DI != BB.end(); ) {
    Instruction *Inst = DI++;
    if (isInstructionTriviallyDead(Inst)) {
      Inst->eraseFromParent();
      Changed = true;
      ++DIEEliminated;
    }
  }
  return Changed;
}