【问题标题】:How to tell if LLVM Instruction has a Left-Hand Side如何判断 LLVM 指令是否有左侧
【发布时间】:2016-04-24 06:17:16
【问题描述】:

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

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

【问题讨论】:

  • 您是否需要在您的代码中执行这样的检查,或者您只是想知道哪条指令可能有或可能没有结果赋值?
  • 如果指令的值没有使用或用户,则该指令没有左侧

标签: llvm llvm-ir


【解决方案1】:

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

这是因为您没有 来分配操作的结果。例如,以下代码行在 LLVM IR 中有效:

add nsw i32 %a, %b

但这毫无意义,因为它没有任何作用。没有任何理智的工具会发出该行,即使发出,它也会在死代码消除期间被优化器清除。忽略返回值实际上是有意义的唯一指令是call。事实上,您可能只想为副作用调用一个函数,即使它没有声明为void。想想 C 语言中的 printf,它的返回值几乎总是被忽略。

由于最后一个考虑,您可以假设实际上所有可以进行结果赋值的指令都有一个,唯一的例外是callinvokecall 非常相似,因此适用于前者的相同考虑。

您可能已经注意到,一条指令是否会导致赋值取决于它的类。借助包含所有操作码和类的定义的llvm/IR/Instruction.defthe IR language reference,我们可以得出以下细分:

不能有结果赋值的指令类:

  • ReturnInst, BranchInst, SwitchInst, IndirectBrInst, ResumeInst, UnreachableInst, CleanupReturnInst, CatchReturnInst
  • StoreInst, FenceInst, AtomicRMWInst, AtomicCmpXchgInst

(可能)有结果赋值的指令类:

  • CatchSwitchInst
  • BinaryOperator
  • AllocaInst, LoadInst, GetElementPtrInst
  • InvokeInst, CatchSwitchInst
  • TruncInst, ZExtInst, SExtInst, FPToUIInst, FPToSIInst, UIToFPInst, SIToFPInst, FPTruncInst, FPExtInst, PtrToIntInst, PtrToIntInst, @98765434
  • VAArgInst
  • CleanupPad, 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; }

  // ...
};

【讨论】:

    【解决方案2】:

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

    getType()->isVoidTy()
    

    【讨论】:

      猜你喜欢
      • 2011-06-03
      • 2010-12-06
      • 2021-12-25
      • 2016-08-30
      • 2016-09-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多