new register allocator and HARD_REGNO_CALL_PART_CLOBBERED

Michael S. Zick mszick@goquest.com
Fri May 16 14:17:00 GMT 2003


On Friday 16 May 2003 06:35 am, Michael Matz wrote:
> Hi,
>
> On 15 May 2003, Alexandre Oliva wrote:
> > Partial saves added a new twist that rth and I hadn't considered when
> > we talked about this feature and came up with the design above a few
> > days ago.  Presumably we could have per-mode bitsets as well (or
> > instead of) absolute saved/clobbered definitions added to the
> > call insn clobbered data structure.
> >
 - - - -
>
> > The exact way to represent the ABI requirements is secondary, and the
> > design is definitely open for discussion.
 - - - -
Earlier in this thread the topic was limited to "calls within a compilation
unit" - "internal calls".  Either to a function explicitly written as such in
the source or implicit functions, those derived by the "common
sub-expression" identifiers.

That would be case one - Decision one: Do we attempt to enforce
ABI requirements on such calls or only require caller/callee
agreement?

Case two would be "calls internal to the program unit" - calls to
functions external to the current compilation unit but NOT external
to the final program unit.  I.E: Not a library function.
Decision two: same as decision one.

Case three is "calls external to the program unit" - There is no
decision three - these MUST meet ABI requirements.

Case two is not likely to occur within the limits of GCC's current
design.
Case one is not easy to do, but can yield big wins; In relaxed
restrictions on register allocation (register pressure escapes)
and the size of functions (both kinds) for which the decision is
made to not-in-line.

Let me propose a scheme that handles all three.

At the point of call, record three register constraints per register.
1) Argument Present.
2) Save/Restore if used.
3) Available
Represent only (1) and (2) since (3) is whatever is left over.
Use a bitset to represent each of (1) and (2) - each bit
corresponding to a register.

Next question: "What is a register?"
Or perhaps, better stated: "What degree of granularity will
be represented for a register?"

D... I hate decision making - that is either #3 or #4 now.

If the machine has a 32 bit register that is also addressable
in 8 bit units - does it get 1 bit in each constraint array or 
4 bits?
Same considerations for other size combinations.

What about a Condition Code register that is (implicitly)
bit addressable?  I.E: shall we allow a boolean argument
to be passed in the Zero Flag?  (Messy but effective).
What about machines that allow arbitrary size and position
bit fields of registers to be directly accessed with field
insert/extract instructions?  Now there is a challenge for
the bit-mask scheme I am describing.

Obviously those two bit arrays will need a "mode" indicator.
The 0 mode (or the only mode) per the last numbered
decision (one bit per addressable element of a register).
The other modes (if any) might be a more complicated
structure than a pair of bit arrays.

A few notes:

1) There is only one pair of bit arrays which describe
the ABI requirements - they can be represented either
explicitly or implicitly by its absence.  In the implicit case,
the ABI requirements are dealt with per current practice.

2) The "return" from the call can use the same scheme
to specify where the result is located.

3) The bit array scheme can be extended to include
a "read only" constraint.

4) The bit array scheme can be extended to include
the stack frame (if an argument is available several
frames prior to this call - why move it, use it in-place.)

6) One of the purposes of those bit arrays is to coalesce
register usage at multiple points-of-call into a single
callee expected pattern (This is the hard part where
you trade-off reduced register pressure concerns with
inspecting code paths into all calls so that all callers
reach the same argument layout that you will LATER
code the callee to expect.)



More information about the Gcc mailing list