如何判断LLVM指令是否具有左侧 [英] How to tell if LLVM Instruction has a Left-Hand Side
问题描述
是否可以判断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
指令的左侧.但是,store
或br
指令不会.
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
. invoke
与call
非常相似,因此适用于前者的相同考虑.
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:
-
ReturnInst
,BranchInst
,SwitchInst
,IndirectBrInst
,ResumeInst
,UnreachableInst
,CleanupReturnInst
,CatchReturnInst
-
StoreInst
,FenceInst
,AtomicRMWInst
,AtomicCmpXchgInst
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
,IntToPtrInst
,BitCastInst
-
VAArgInst
-
CleanupPad
,CatchPad
-
ICmpInst
,FCmpInst
,PHINode
,SelectInst
-
ExtractElementInst
,ShuffleVectorInst
,ExtractValueInst
,InsertElementInst
,InsertValueInst
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
-
CallInst
,InvokeInst
您现在可以在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屋!