This is the mail archive of the gcc@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]

Re: Liberating structs from memory



  In message <200008182034.NAA16501@kayak.mcgary.org>you write:
  > I wish to begin discussion about how to improve gcc's handling of auto
  > variable structs whose address is never taken.  Such structs need not
  > reside in memory, and would be better treated as if all members were
  > separate variables, individually assignable to registers.
Yup.  This is commonly referred to as scalar replacement of aggregates and
typically happens relatively early in the compilation process.

I think this is most easily done at the tree level -- except that we do not
have functions as trees for most of the front-ends yet, so it's hard to know
if an auto has had its address taken until its too late.

  > Special consideration must be given to structs passed (and returned)
  > by value.  On RISC machines, such structs need to be spilled to a
  > temporary in memory and the address of the temporary passed to the
  > callee.  Similar for return values: the caller allocates an in-memory
  > temporary and passes a hidden first argument with its address.  The
  > callee stuffs the return value into memory at that address.  A naive
  > first implementation should probably consider a struct passed by value
  > as one whose address is taken.
Agreed.  Note that you've over-simplified things in terms of what systems
do with pass by invisible reference structures -- some ABIs have the copy
made by the callee (which allows the callee to avoid the copy if it never
modifies the structure).


  > However, even in a first implementation, I wish to treat BPs
  > specially: they should always be passed and returned by value in
  > registers whenever possible.  When passing, they would be logically
  > treated as three consecutive simple pointer args.  When returning,
  > they would be placed in three consecutive return-value registers.  On
  > ix86, that would be %eax, %edx, %ecx.  On PowerPC, that would be r3,
  > r4, r5.  Even though MIPS ABI has only two value-return registers, we
  > can use `a0' as a third, since this entire BP-passing scheme goes
  > beyond the ABI.
Conceptually it's like the structure passing conventions for PA64 and
I believe the latest sparc ABIs -- you conceptually lay out an argument
list in memory, then copy as much of it as possible into a series of
registers (again that's the conceptual model -- that's not actually how
its done).


  > It seems conceptually simple enough to implement: instead of DECL_RTL
  > being a MEM for the entire struct, make it some form of table (vector
  > or list or whatever) that holds an RTX for each member of the struct.
  > Expanding a COMPONENT_REF will do a lookup to find the proper RTX.
  > The table can be sparse, omitting RTXes for members that are unused.
  > If the struct's address is taken, we toss the table and revert to the
  > traditional MEM.  Taking the address of a member should force only
  > that member into memory, not the entire struct.
Seems generally reasonable, though you've got to fight the problem of
dumping stuff to memory *after* you've already creates its DECL_RTL.  In
a number of ways it's similar to the ADDRESSOF problem where we have these
magic tidbits lying around for a while then after various optimizations we
have to convert them to sensible RTL.

jeff



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