I am trying to write a code to do the following:
Get an ARM machine instruction
Find destination register of that instruction that has been written
set a bit in a vector, according to that register number. (Since it’s ARM, I have a 15 bit vector)
It means if I have :
add r0, r1, r0
I want to get r0 as dest reg and set the index 0 of my vector to 1.
I get my machine instruction, but I don’t know how to get dest reg. I looked at MachineInstr.h but couldn’t find it out.
Also I want to know which instructions to excluse from this routine, for example str instruction does not write to a dest reg or branch instruction. Are there any other instruction.
Thanks for your help,
I get my machine instruction, but I don't know how to get dest reg. I looked
at MachineInstr.h but couldn't find it out.
You probably want to iterate through the instruction's operands
(MachineInstr::operands_begin/end) looking for defines ("isDef") of
the registers you care about. Some instructions will write multiple
registers (e.g. ldrd), and the information is in a certain sense
approximate (an empty inline asm block may be marked as writing some
registers, but not actually do anything).
A call instruction "BL" also gets marked with the registers the
function uses for return values so that LLVM can track data-flow. You
may or may not want that, if not then looking for non-implicit
(!isImplicit) defines might be a better approximation.
Finally, you probably have to be aware of subregisters even for GPRs,
the ARM-mode ldrd instructions can only take sequential pairs, which
LLVM models as a separate register called something like R0_R1.
Also I want to know which instructions to excluse from this routine, for
example str instruction does not write to a dest reg or branch instruction.
That's why you should check isDef for the ones you're after.
Thank you for your thorough reply. So, based on your reply I get every operand and check them to be (isDef && !isimplicit). Now my problem is that it gives me the physical register number.i.e, for example, instead of r0, it return %physreg66. Could you please help me on how to convert these physical register number to the ARM related register? I mean the 15 GPRs in ARM.
You should be able to compare them to the generated enum:
"Op->getReg() == ARM::R0" for example. Alternatively you could use
"MCRegisterInfo::getEncodingValue" on "Op->getReg()", which would
return 0-15 for the basic registers.
Thank you so much.
I want to use ARM::R0, because I’m going to need this style for evaluating opcodes as well. Forgive me if this is a stupid question question, but I don’t know how to include this information in my code. I think I have to include “ARMBaseInfo.h”, and #include “…/lib/Target/ARM/ARMBaseInfo.h” does not work!
Forgive me if this is a stupid question question, but I
don't know how to include this information in my code. I think I have to
include "ARMBaseInfo.h", and #include "../lib/Target/ARM/ARMBaseInfo.h" does not work!
If your pass is ARM-specific, you'd usually put it in the
lib/Target/ARM directory (e.g. ARMLoadStoreOptimizer.cpp). This is
mainly because generic libraries (e.g. libLLVMCodeGen.a) aren't
allowed to depend on individual targets being present. LLVM can be
built without any ARM support at all, in which case ARMBaseInfo.h
(etc) just couldn't be included.
From lib/Target/ARM, you should just be able to '#include
"ARMBaseInfo.h"'. Though it's more likely to be ARMRegisterInfo.h you
want, for what you've mentioned at least.