[PATCH] D33562: MachineLICM: Add new condition for hoisting of caller preserved registers

Nemanja Ivanovic via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue May 30 14:13:05 PDT 2017


nemanjai added a comment.

In https://reviews.llvm.org/D33562#767911, @sfertile wrote:

> In https://reviews.llvm.org/D33562#767893, @iteratee wrote:
>
> > In https://reviews.llvm.org/D33562#766989, @nemanjai wrote:
> >
> > > > You talk about a call instruction? Is X2 saved and restored in the called function? Then it's just a CSR and should not be mentioned in the clobber list so no problem with my proposal above.
> > >
> > > But it is the caller that saves and restores it, not the callee. The sequence is essentially this (all in the caller of course):
> > >
> > > - Save X2 to it's stack slot
> > > - Update X2 prior to the call
> > > - Call the function through a pointer
> > > - Restore X2 immediately after the call
> >
> >
> > But all of that occurs via the linker.
> >  X2 is saved by a trampoline if necessary, and restored in the nop slot if necessary.
> >  As far as the surrounding code is concerned, the trampoline is the callee, (the nop slot may be considered part of the trampoline.)
> >  Treating X2 as callee saved makes perfect sense as far as llvm is concerned.
>
>
> For a normal call the linker inserts the save and restore. When calling through a function pointer the compiler inserts the save/restore of the TOC pointer, and that  is what is causing the address calculations not to get hoisted.


Just for reference... Here's what Machine LICM sees for the call through a function ptr:

`BCTRL8_LDinto_toc 24, %X1, <regmask %CR2 %CR3 %CR4 %F14 %F15 %F16 %F17 %F18 %F19 %F20 %F21 %F22 %F23 %F24 %F25 %F26 %F27 %F28 %F29 %F30 %F31 %R14 %R15 %R16 %R17 %R18 %R19 %R20 %R21 %R22 %R23 %R24 %R25 %R26 %R27 %R28 %R29 %R30 %R31 %V20 %V21 %V22 %V23 %V24 %V25 %V26 %V27 %V28 %V29 %V30 %V31 %VF20 %VF21 %VF22 %VF23 %VF24 %VF25 %VF26 %VF27 %VF28 %VF29 %VF30 %VF31 %X14 %X15 %X16 %X17 %X18 %X19 %X20 %X21 %X22 %X23 %X24 %X25 %X26 %X27 %X28 %X29 %X30 %X31 %CR2EQ %CR3EQ %CR4EQ %CR2GT %CR3GT %CR4GT %CR2LT %CR3LT %CR4LT %CR2UN %CR3UN %CR4UN>, %LR8<imp-def,dead>, %X2<imp-def,dead>, %CTR8<imp-use>, %RM<imp-use>, %X3<imp-use>, %X12<imp-use>, %X2<imp-use>, %R1<imp-def>, %X3<imp-def>`

And of course, this "instruction" will emit both the branch on the count register and the load into X2 to restore the TOC pointer. Of course, previously to this, `prepareCall()` will have emitted a store of the TOC pointer to the stack.

So it really is the caller that saves and restores the TOC ptr. So X2 is not a CSR - the caller modifies it so it is of course not a "constant physical register". The only thing that makes this situation special is that what needs to be communicated to Machine LICM is that this modification is guaranteed to give X2 the same value it had before the call.


https://reviews.llvm.org/D33562





More information about the llvm-commits mailing list