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

dam*_*ard 6 llvm

我有followint 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
Run Code Online (Sandbox Code Playgroud)

在其中我首先加载%1中的可变"i"和%2中的变量"j"然后我比较大于条件(i> j).基于此,有分支标记4或标记6.我的问题是变量"i"有两个加载指令,第一个基本块中的一个和第二个基本块中的另一个.这里我想删除第二个加载指令.为此我正在这样做,因为当我达到变量"i"的第二个加载指令时,我正在用第一个指令替换第二个指令的所有用法然后我正在擦除当前指令,即第二个.这里我无法设置指令迭代器指针.我不想设置下一条指令(存储i32%5,i32*%k,对齐4).还有其他方法吗?如果您知道,请告诉我.

Eli*_*sky 11

如果我理解正确,你只需要擦除指令并继续迭代代码.如果这是正确的,请从DeadInstElimintation传递(它存在lib/Transforms/Scalar/DCE.cpp)中查看此示例:

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;
}
Run Code Online (Sandbox Code Playgroud)

有趣的是要注意迭代器是如何递增的.这DI++不是在最后一个子句内完成的for,而是分开的,DI分配给当前的Inst.这确保即使您删除Inst,也DI已指向下一条指令,因此循环将继续在下一条指令上运行.