forked from facebook/hhvm
-
Notifications
You must be signed in to change notification settings - Fork 3
Branch taking too many instructions
Gustavo Serra Scalet edited this page Jun 9, 2016
·
3 revisions
Currently, a JIT branch code can be as big as the following in PPC64:
- e.g: branching to
0x16c70820
(HPHP::jit::traceCallback)
0x202021bc: lis r12,5831 # loading 0x16c7 on r12 (high)
0x202021c0: ori r12,r12,2080 # loading 0x0820 on r12 (low)
0x202021c4: nop # reserved for a shift, in case more bits are needed
0x202021c8: nop # reserved for highest bits
0x202021cc: nop # reserved for higher bits
0x202021d0: mtctr r12
0x202021d4: nop # reserved for overflow handling (xor r0, r0, r0)
0x202021d8: nop # reserved for overflow handling (mtspr XER, r0)
0x202021dc: bctrl # proper branch with LR save
0x202021e0: ld r2,24(r1) # restore TOC pointer
There are too many instructions for something that simple. Some important aspects to note:
- CTR register, which you have to set the absolute address (5 instructions + mtctr + bctrl)
- Addressing is too far. The 'b' instruction is able to handle an offset of up to 26 bits but those are currently too far away. (0x202021bc - 0x16c70820 = 156834204 > 0x3ffffff)
- The "nop"s used are reserving instructions for setting the target address as an internal branch can have an unknown target when being emitted (the target is still not emitted, so you don't know how far it's). For that reason "nop"s are emitted in order to be replaced afterwards (in a process called patch), in case more instructions are needed in order to have the correct target address.
- Some possible improvements:
- The distance between branch and target can be reduced by using relocation, which moves blocks of codes nearer to its caller. This reduces the offset size of a branch and makes it possible for other instructions to be used (only a "b" instead of the 7 instructions emitted by the usage of a CTR register). (See https://github.com/PPC64/hhvm/issues/53 for development info)
- Usage of the TOC pointer to store targets of a branch and then use it like PLT calls: (See https://github.com/PPC64/hhvm/issues/134 for development info)
0x100003e4 <00000017.plt_call.puts@@GLIBC_2.17+4>: ld r12,-32696(r2)
0x100003e8 <00000017.plt_call.puts@@GLIBC_2.17+8>: mtctr r12
0x100003ec <00000017.plt_call.puts@@GLIBC_2.17+12>: bctr