This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Unrevied patches^3


[Rearranging the original message a bit.]

Geoff Keating <geoffk@geoffk.org> writes:
> I don't understand what you mean by "the high part is a load from the
> GOT".  If you can load the high part from the GOT, why don't you just
> load the whole address from there?

For local symbols, we load a page address from the GOT and use a LO_SUM
to access something within the page.  E.g. (assuming no small data):

     static int x;

would be accessed with a sequence such as:

     lw     r1,%got($gp)          # (set (reg r1) (mem (plus $gp ...)))
     lw     r2,%lo(r1)            # (set (reg r2) (lo_sum (reg r1) ...))

or:

     lw     $4,%got_page($gp)
     lw     $4,%got_ofst($4)

depending on the ABI.

> Richard Sandiford <rsandifo@redhat.com> writes:
> > Geoff Keating <geoffk@geoffk.org> writes:
> > > This patch isn't right.  What is the MIPS port doing that it has a
> > > LO_SUM without a corresponding HIGH?  Why can it not represent this
> > > using PLUS, or some other arithmetic operation, instead?
> > 
> > I don't understand.  The LO_SUM does have a high part, but it isn't
> > always represented as a HIGH:
> > 
> >    - If the symbol refers to small data, the high part is $gp
> >      (this is like what the alpha port does, except the alpha
> >      port only uses it after reload).
> > 
> >    - When generating PIC, the high part is a load from the GOT.
> >      It's represented as such even before reload (which this makes
> >      various things easier).
> > 
> > Are you saying that the first operand to a LO_SUM must be provided
> > specifically by a HIGH, rather than some other "more specific"
> > rtx that evaluates to the same thing?
> 
> You should probably look up the documentation for LO_SUM and HIGH.
> 
> It doesn't have to be represented as a HIGH, it is usually a register.

Yes, I know. ;)  The code I'm touching is dealing with cross-instruction
optimisations.  I.e. they've seen an insn containing:

     (lo_sum (reg X) (symbol_ref "foo"))

and found the definition of X to be:

     (set (reg X) (high (symbol_ref "foo")))

They then realise that the (lo_sum ....) actually has the value "foo".

Setting aside the small data thing, all I'm trying to do is extend these
optimisations so that they recognise target-specific reprsentations of
the high part.  So if X was instead defined to be:

     (set (reg X) (mem:SI (plus (gp)
                                (const (unspec [(symbol_ref "foo")]
                                               UNSPEC_GOT_PAGE)))))

and the backend said that this MEM was equivalent to the HIGH value
above, then they'd be able to optimise it in the same way.

I know there's a school of thought that pic accesses shouldn't be
exposed until after reload.  But other ports already do expose them
before reload, MIPS wasn't the first.  That's why we have
delegitimize_address, etc.

This new hook is like delegitimize_address except that it applies to
the high part of the address, not the full value.

> I'm not completely sure how MIPS small data works, but I thought it
> didn't do this.  I thought that the point of using small data was that
> the offset to it did not have a high part (it fits in 16 signed bits,
> thus "small"), and that the register used as a base was fixed.  In
> that case, I would recommend simply writing
> 
> (set ... (symbol_ref "foo"))
> 
> and leaving $gp out of it.  (This is what rs6000 does, and HIGH/LO_SUM
> was originally invented for rs6000.)

The problem with this is that small data accesses are possible in
n32/n64 PIC, in which $gp is set up by the callee.  So if we used a
plain symbol_ref, we'd have to put back various scheduling barriers in
the prologue and epilogue (barriers that we used to have, but could be
removed after the rewrite).  That's likely to pessimise small functions.

Besides, MIPS isn't the first port to use $gp as the high part of a
LO_SUM.  The idea was borrowed from the alpha port and IMO it makes
sense.  (lo_sum (reg X) (symbol_ref "small_data_symbol")) is written
out as:

    %gp_rel(X)

and $gp really _is_ the high part of this value.

Richard


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]