如何判断LLVM指令是否有左侧

如何判断LLVM指令是否有左侧,llvm,llvm-ir,Llvm,Llvm Ir,有没有办法判断LLVM指令是否有左手边?也就是说,它是否产生了价值 例如,add指令将有一个左侧;但是,存储或br指令不会。通常,您可以识别那些不能进行结果赋值的指令,但不能说指令是否会导致赋值,只能说它可能会 这是因为您不必指定操作的结果。例如,以下代码行在LLVM IR中有效: add nsw i32 %a, %b 但这毫无意义,因为它没有任何效果。任何理智的工具都不会发出该行代码,即使发出了该行代码,优化器也会在消除死代码的过程中删除该行代码。忽略返回值真正有意义的唯一指令是call。事

有没有办法判断LLVM
指令是否有左手边?也就是说,它是否产生了价值


例如,
add
指令将有一个左侧;但是,
存储
br
指令不会。

通常,您可以识别那些不能进行结果赋值的指令,但不能说指令是否会导致赋值,只能说它可能会

这是因为您不必指定操作的结果。例如,以下代码行在LLVM IR中有效:

add nsw i32 %a, %b
但这毫无意义,因为它没有任何效果。任何理智的工具都不会发出该行代码,即使发出了该行代码,优化器也会在消除死代码的过程中删除该行代码。忽略返回值真正有意义的唯一指令是
call
。事实上,您可能只想为副作用调用函数,即使它没有声明为void。考虑一下C中的
printf
,它的返回值几乎总是被忽略

由于最后一点考虑,您可以假设在实践中,所有可能具有结果赋值的指令都将具有结果赋值,只有
call
除外
invoke
call
非常相似,因此对前者的考虑同样适用

正如您可能已经注意到的,指令是否会导致赋值取决于它的类。借助的,其中包含所有操作码和类的定义,以及,我们可以得出以下细分:

不能有结果赋值的指令类:
  • ReturnInst
    BranchInst
    SwitchInst
    IndirectBrInst
    ResumeInst
    UnreachableInst
    cleanupreturinst
    CatchReturnInst
  • StoreInst
    FenceInst
    AtomicRMWInst
    AtomicCmpXchgInst
(可能)具有结果赋值的指令类:
  • CatchSwitchInst
  • BinaryOperator
  • AllocaInst
    LoadInst
    GetElementPtrInst
  • InvokeInst
    CatchSwitchInst
  • TruncInst
    ZExtInst
    SExtInst
    FPToUIInst
    FPToSIInst
    UIToFPInst
    sitofinst
    FPTruncInst
    fpexist
    pttoinst
  • vaargist
  • CleanupPad
    CatchPad
  • ICmpInst
    FCmpInst
    PHINode
    选择inst
  • ExtractElementInst
    ShuffleVectorInst
    ExtractValueInst
    InsertElementInst
    InsertValueInst
可能有或可能没有结果赋值的指令类:
  • CallInst
    InvokeInst
现在,您可以在
指令::getOpcode()
的结果上构建一个
开关
,或者更好的是,构建一个对指令进行分类的开关:

#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; }

  // ...
};
#包括
enum HaveRetVal{肯定不是,也许,可能是};
课程名称:公共设施访客{
公众:
HaveRetVal visitBinaryOperator(BinaryOperator&){return可能_YES;}
// ...
HaveRetVal VisitCallist(CallInst&){return MAYBE;}
// ...
HaveRetVal visitBranchInst(BranchInst&){返回肯定不;}
// ...
};

您可以检查指令的返回类型是否为
void

getType()->isVoidTy()

您是否需要在代码中执行这样的检查,还是只想知道哪个指令可能有或可能没有结果赋值?如果指令的值没有uses或user,那么该指令就没有左手边