Reputation: 81
I'm a newbie in llvm, and I'm trying to find all the function call instructions in IR. My code is shown below:
for (BasicBlock &BB : F) {
for (Instruction &inst : BB) {
errs() << "\n => " << inst << "\n";
// if (dyn_cast<CallInst>(&inst) || dyn_cast<InvokeInst>(&inst)) {
if(inst.getOpcode() == Instruction::Call || inst.getOpcode() == Instruction::Invoke) {
errs() << "\n callinst => " << inst << "\n";
}
}
}
But this doesn't work to find the function call instructions. For example, for this instruction:
call void @func2(i32* %num)
The code cannot find it.
And I did some experiment for this instrucion:
inst.getOpcodeName() == "call"
inst.getOpcode() == 56
But:
Instruction::Call == 54
Instruction::UserOp1 == 56
I have some questions:
Upvotes: 6
Views: 3707
Reputation: 176
Actually, your code is correct. As of the latest commits in the llvm mirror, the opcode of the call instruction is not 54 anymore, but 56. In November 13, 2018 it was changed to 55 and in February 8, 2019, it was changed to 56.
The Opcode for UserOp1 is now 58.
To your questions:
1) The right way to identify call instructions, as well as any other type of instruction is to use the isa<>()
function. The template argument is the type you are seeking to identify and the function argument your instruction pointer. In your example, you could change your if condition to:
if(isa<CallInst>(&inst) || isa<InvokeInst>(&inst)) {
The reason of why you would prefer to do this over comparing opcodes is pretty obvious. As you can see, new instructions can be added and the opcodes can be changed. So comparing opcodes becomes incompatible pretty fast. Using the 'isa' function will always return true if the types match, regardless of the opcodes. Check docs for this function here: http://llvm.org/docs/ProgrammersManual.html#the-isa-cast-and-dyn-cast-templates
2) UserOp1 is a type of instruction used only internally in passes. As far as I know, it is also used by the llvm framework in a few functions to take care of some corner cases. You can never read or write a 'UserOp1' (or UserOp2) instruction to an IR. You need not care about this type. See also here: How to use UserOp1/UserOp2 instruction?
3) You probably are using the latest version of the framework, and this is why you get an output of 56 for call instructions. You might have been confused because you compared this output with a slightly outdated Instructions.def file which maps the call instruction to an opcode of 54.
Upvotes: 10