如何判断LLVM指令是否具有左侧 [英] How to tell if LLVM Instruction has a Left-Hand Side

查看:184
本文介绍了如何判断LLVM指令是否具有左侧的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is there a way to tell if an LLVM Instruction has a left-hand side? That is, whether it produces a value?

例如,一条add指令的左侧.但是,storebr指令不会.

For example, an add instruction would have a left-hand side; however, a store or br instruction would not.

推荐答案

通常,您可以识别不能进行结果分配的指令,但是您无法确定指令是否会导致结果分配,只有它可能.

In general you can identify those instructions which cannot have a result assignment, but you cannot say if an instruction will result in an assignment, only that it might.

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

This is because you don't have to assign the result of an operation. For instance, the following line of code is valid in LLVM IR:

add nsw i32 %a, %b

但这是没有意义的,因为它没有任何作用.没有理智的工具会发出该行,即使发出该行,在消除死代码的过程中,优化程序也会将其抹去.唯一忽略返回值的指令实际上是call.实际上,您可能只想为副作用而调用函数,即使未声明void时也是如此.考虑一下C语言中的printf,其返回值几乎总是被忽略.

but it's pointless because it has no effect whatsoever. No sane tool would emit that line, and even if emitted, it would be wiped away by the optimizer during dead code elimination. The only instruction for which ignoring the return value actually makes sense is call. In fact, you might want to call a function only for side-effects, even when it's not declared void. Think about printf in C, whose return value is almost invariably ignored.

由于这最后一个考虑,您可以假设实际上所有可以进行结果分配的指令都具有一个指令,唯一的例外是call. invokecall非常相似,因此适用于前者的相同考虑.

Because of this last consideration, you can assume that in practice all the instructions that can have a result assignment will have one, with the only exception of call. invoke is very similar to call, so the same considerations made for the former apply.

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

As you might have noticed, whether an instruction results in an assignment depends on its class. With the help of llvm/IR/Instruction.def, which contains the definition of all opcodes and classes, and the IR language reference, we can come up with the following subdivision:

  • ReturnInstBranchInstSwitchInstIndirectBrInstResumeInstUnreachableInstCleanupReturnInstCatchReturnInst
  • StoreInstFenceInstAtomicRMWInstAtomicCmpXchgInst
  • ReturnInst, BranchInst, SwitchInst, IndirectBrInst, ResumeInst, UnreachableInst, CleanupReturnInst, CatchReturnInst
  • StoreInst, FenceInst, AtomicRMWInst, AtomicCmpXchgInst
  • CatchSwitchInst
  • BinaryOperator
  • AllocaInstLoadInstGetElementPtrInst
  • InvokeInstCatchSwitchInst
  • TruncInstZExtInstSExtInstFPToUIInstFPToSIInstUIToFPInstSIToFPInstFPTruncInstFPExtInstPtrToIntInstIntToPtrInstBitCastInst
  • VAArgInst
  • CleanupPadCatchPad
  • ICmpInstFCmpInstPHINodeSelectInst
  • ExtractElementInstShuffleVectorInstExtractValueInstInsertElementInstInsertValueInst
  • CatchSwitchInst
  • BinaryOperator
  • AllocaInst, LoadInst, GetElementPtrInst
  • InvokeInst, CatchSwitchInst
  • TruncInst, ZExtInst, SExtInst, FPToUIInst, FPToSIInst, UIToFPInst, SIToFPInst, FPTruncInst, FPExtInst, PtrToIntInst, IntToPtrInst, BitCastInst
  • VAArgInst
  • CleanupPad, CatchPad
  • ICmpInst, FCmpInst, PHINode, SelectInst
  • ExtractElementInst, ShuffleVectorInst, ExtractValueInst, InsertElementInst, InsertValueInst
  • CallInstInvokeInst

您现在可以在Instruction::getOpcode()的结果上构建switch,或者更好地在 InstVisitor 来对指令进行分类:

You can now build a switch on the result of Instruction::getOpcode() or, better, an InstVisitor to classify instructions:

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

  // ...
};

这篇关于如何判断LLVM指令是否具有左侧的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆