[LLVMdev] Register Pairing

Borja Ferrer borja.ferav at gmail.com
Wed Dec 1 13:02:04 PST 2010


Jeff thanks for those suggestions, that's exactly what i would like to do,
however i dont know how to do it with my current knowledge :\ As far as i
understand patterns only take one instruction as an input (while the pattern
you wrote before takes two) and also, i dont know how to handle register
copying (COPY) in the .td file because they're handled in a different way to
the rest of instructions.

Jakob i know my approach is not very suitable watching the results i got.
The example i wrote in my previous email was just a trivial function to see
if what i was trying to do was good.
Without doing what i mentioned and letting LLVM expand all operations wider
than 8 bits as you asked, the code produced is excellent supposing that many
of the moves there should be 16 bit moves reducing code size and right
register allocation, also something important for me is that the code is
better than gcc's. When i say right reg allocation it doesnt mean it's doing
things wrong, i mean it's getting regs freely without pairing regs because i
dont know how to do it. So now i have to push things further and implement
these details to make the backend introduce those 16 bit instructions i dont
know how to insert, and this is where i need help.

My 2 big questions are:

- How to tell the register allocator to store 16 bit data in two contiguous
8 bit regs being the low part an even reg? Remember data would be expanded
into 8 bit ops, so when we're working with dags after type legalization do
we really know the original type before expansion?
As an example, storing a short in r21:r20 would be valid, but r20:r19 or
r20:r18 would be invalid because the in the first case the low reg is odd
and in the second case regs arent contiguous.
To store data wider than 16 bits, for example for a 32 bit int we would use
2 register pairs (4 8bit regs) but here the pairs dont need to be contiguous
so storing it r25:r24:r19:r18 is completely fine.
As i said in my previous email this is achieved by using HARD_REGNO_MODE_OK
in gcc.

- Second, assuming the previous point works so the register constraints are
done, how would i then proceed and combine two 8 bit instructions into a 16
bit one as Jeff pointed out in his email?
For example i want to combine a 16 bit add like this:
// b = b + 1:
(b stored in r25:r24)
add r24, 1
adc r25, 0
into
adw r25:r24, 1

and the one im talking all my mails about
move r25, r23
move r24, r22
into
movw r25:r24, r23:r22

or
move r18, r2
move r19, r3
into
movw r19:r18, r3:r2
any combination of moves with reg pairs are valid.

I wrote a function pass to test, it scanned for moves and checked if next
instruction was a move to see if globally it was a 16 move and replace those
2 insts with a movw. But this pass lacked lots of details for example if a
different instruction was placed in between the moves it wouldnt be able to
detect it.

Your help is really appreciated, and thanks to both for your patience.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20101201/fc30c2c6/attachment.html>


More information about the llvm-dev mailing list