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

jgo*_*ers 2 llvm llvm-ir

有没有办法判断LLVM Instruction是否具有左侧?也就是说,它是否产生价值?

例如,一条add指令将具有左侧。但是,storebr指令不会。

小智 7

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

getType()->isVoidTy()
Run Code Online (Sandbox Code Playgroud)


Ste*_*ppo 5

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

这是因为你不具备分配一个操作的结果。例如,以下代码行在LLVM IR中有效:

add nsw i32 %a, %b
Run Code Online (Sandbox Code Playgroud)

但这毫无意义,因为它毫无作用。没有理智的工具会发出该行,即使发出,在消除死代码的过程中,优化程序也会将其擦除。真正忽略返回值的唯一指令是call。实际上,您可能只想为副作用调用一个函数,即使未声明它也是如此void。考虑一下printfC,它的返回值几乎总是被忽略。

出于最后的考虑,您可以假定实际上所有可以进行结果分配的指令都将具有一个指令,唯一的例外是callinvoke与十分相似call,因此适用于前者的相同考虑。

您可能已经注意到,一条指令是否导致赋值取决于其类。借助llvm/IR/Instruction.def,它包含所有操作码和类的定义以及IR语言参考,我们可以提出以下细分:

无法分配结果的指令类:

  • ReturnInstBranchInstSwitchInstIndirectBrInstResumeInstUnreachableInstCleanupReturnInstCatchReturnInst
  • StoreInstFenceInstAtomicRMWInstAtomicCmpXchgInst

(可能)具有结果分配的指令类:

  • CatchSwitchInst
  • BinaryOperator
  • AllocaInstLoadInstGetElementPtrInst
  • InvokeInstCatchSwitchInst
  • TruncInstZExtInstSExtInstFPToUIInstFPToSIInstUIToFPInstSIToFPInstFPTruncInstFPExtInstPtrToIntInstIntToPtrInstBitCastInst
  • VAArgInst
  • CleanupPadCatchPad
  • ICmpInstFCmpInstPHINodeSelectInst
  • ExtractElementInstShuffleVectorInstExtractValueInstInsertElementInstInsertValueInst

可能有或没有结果分配的指令类:

  • CallInstInvokeInst

现在,您可以switch根据Instruction::getOpcode()或更好的结果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; }

  // ...
};
Run Code Online (Sandbox Code Playgroud)