【发布时间】:2016-04-24 06:17:16
【问题描述】:
有没有办法判断 LLVM Instruction 是否有左侧?也就是说,它是否产生了价值?
例如,add 指令将有左侧;但是,store 或 br 指令不会。
【问题讨论】:
-
您是否需要在您的代码中执行这样的检查,或者您只是想知道哪条指令可能有或可能没有结果赋值?
-
如果指令的值没有使用或用户,则该指令没有左侧
有没有办法判断 LLVM Instruction 是否有左侧?也就是说,它是否产生了价值?
例如,add 指令将有左侧;但是,store 或 br 指令不会。
【问题讨论】:
一般而言,您可以识别那些不能进行结果赋值的指令,但你不能说指令是否会导致赋值,只能说它可能。
这是因为您没有 来分配操作的结果。例如,以下代码行在 LLVM IR 中有效:
add nsw i32 %a, %b
但这毫无意义,因为它没有任何作用。没有任何理智的工具会发出该行,即使发出,它也会在死代码消除期间被优化器清除。忽略返回值实际上是有意义的唯一指令是call。事实上,您可能只想为副作用调用一个函数,即使它没有声明为void。想想 C 语言中的 printf,它的返回值几乎总是被忽略。
由于最后一个考虑,您可以假设实际上所有可以进行结果赋值的指令都有一个,唯一的例外是call。 invoke 与 call 非常相似,因此适用于前者的相同考虑。
您可能已经注意到,一条指令是否会导致赋值取决于它的类。借助包含所有操作码和类的定义的llvm/IR/Instruction.def 和the IR language reference,我们可以得出以下细分:
ReturnInst, BranchInst, SwitchInst, IndirectBrInst, ResumeInst, UnreachableInst, CleanupReturnInst, CatchReturnInst
StoreInst, FenceInst, AtomicRMWInst, AtomicCmpXchgInst
CatchSwitchInstBinaryOperatorAllocaInst, LoadInst, GetElementPtrInst
InvokeInst, CatchSwitchInst
TruncInst, ZExtInst, SExtInst, FPToUIInst, FPToSIInst, UIToFPInst, SIToFPInst, FPTruncInst, FPExtInst, PtrToIntInst, PtrToIntInst, @98765434
VAArgInstCleanupPad, CatchPad
ICmpInst, FCmpInst, PHINode, SelectInst
ExtractElementInst, ShuffleVectorInst, ExtractValueInst, InsertElementInst, InsertValueInst
CallInst, InvokeInst
您现在可以在Instruction::getOpcode() 的结果上构建switch,或者更好的是InstVisitor 来对指令进行分类:
#include <llvm/IR/InstVisitor.h>
enum HaveRetVal { DEFINITELY_NOT, MAYBE, PROBABLY_YES };
class HaveRetAssignment : public InstVisitor<HaveRetAssignment, HaveRetVal> {
public:
HaveRetVal visitBinaryOperator(BinaryOperator &) { return PROBABLY_YES; }
// ...
HaveRetVal visitCallInst(CallInst&) { return MAYBE; }
// ...
HaveRetVal visitBranchInst(BranchInst&) { return DEFINITELY_NOT; }
// ...
};
【讨论】:
可以查看指令的返回类型是否为void:
getType()->isVoidTy()
【讨论】: