LLVM - 活动分析以删除死代码

时间:2016-12-13 20:33:30

标签: c++ llvm compiler-optimization dead-code

我正在尝试实施活动分析以删除死命令。我知道isInstructionTriviallyDead()存在,但是,我想学习如何使用def-use(或use-def)链删除代码。

我目前正在这样做的方式是迭代一个块中的所有指令(使用inst_iterator),并为每个指令循环遍历其所有用途。最终,如果一条指令没用,那么我认为它已经死了,因此可以使用eraseFromParent()删除它

这看起来像:

for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { 
    bool deadInst = true;
    Instruction *inst = &*I;


    for (User* pUser : inst->users()) {
        // If we enter this loop, we have at least one use, so instruction isn't dead
        deadInst = false;
    }

    // deadInst is true if we didn't enter the loop, so has no uses
    if (deadInst) {
        inst->eraseFromParent();
    }
}

问题是,返回指令没有与它相关的用途(我确信还有其他定义没有用)。但是,不应删除返回指令,因为它会导致语义错误的代码。

我通过活体分析删除说明的一般方法好吗?我该怎样做才能确保不会删除返回等指示?

非常感谢任何指针:)

2 个答案:

答案 0 :(得分:0)

还检查指令是否是终止符指令(inst->isTerminator()

答案 1 :(得分:0)

您提到了llvm::isInstructionTriviallyDead,这是一个很好的开始,可以获得有关可以删除的内容和不可删除内容的一些见解。

您已经注意到您无法删除终结符指令。

此外,您不想删除没有使用但有副作用的说明。考虑一下:

define void @bar()() {
  call void @foo()()
  ret void
}

您不想删除call指令,即使它没有用处,因为它可以,例如,写入stdout或更改某些全局变量。同样适用于store。检查Instruction::mayHaveSideEffects以获取完整列表。

您的活跃度分析过于激进:没有必要必要,但不足以条件使指令被视为死亡。

如果您不想将isInstructionTriviallyDead用于学习目的,我建议您从另一个方面开始:考虑指令何时失效(例如,alloca在没有时已经死亡使用,add指令......)然后概括。

此外,只需循环遍历所有指令并删除死指令是不够的。例如:

%2 = add i32 3, %1
%3 = add i32 3, %2

当您第一次遇到%2时,它在%3中有用,所以没有死。但是,在你将%3消灭后,%2也会死亡。你可以通过迭代来解决这个问题,直到找不到新的死命令(无效,但很简单),或者通过一些递归过程。