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: Autoincrement examples



  In message <14315.24602.150585.362111@ongaonga.elec.canterbury.ac.nz>you writ
e:
  > Michael Hayes writes:
  >  > I've also been tidying up a patch that I'm about to submit for a
  >  > separate autoincrement pass that is run as part of flow optimization.
  >  > This collects lists of register references within a basic block and
  >  > uses these lists to look for a sequence of memory references to merge
  >  > with an increment insn.  I found that this approach worked better than
  >  > scanning def-use chains.  
  > 
  > Here's the patches I was referring to.  There are three new files:
  > autoinc.c, ref.c, ref.h.  I've written this as a bolt-on to
  > life_analysis_1 since it completely replaces the autoinc code in
  > flow.c.
  > 
  > I'd be interested in folks' opinions to whether this is the best
  > approach or whether I'm barking up the wrong tree....
  > 
  > For starters, here the docs from autoinc.c:
  > 
  >   There are a number of transformations which can be made by
  >   this optimization:
  > 
  >   case A:
  >   *REG1; REG1 = REG1 + INC  => REG1 = REG1; *REG1++
  > 
  >   case B:
  >   *REG1; REG2 = REG1 + INC  => *REG1++; REG2 = REG1 
  >   where REG1 dies in the add insn.
  >   
  >   case C:  (very uncommon)
  >   *REG1; REG2 = REG1 + INC  => REG2 = REG1; *REG2++
  >   where REG1 is live after the add insn and where REG2 is not used
  >   between the first memref and the add insn.  This case requires
  >   a new move insn to be inserted before the first memref which makes
  >   REG2 live earlier.  However, this won't affect autoinc processing
  >   for REG2 since REG2 is not operand 1 of an add insn.
  > 
  >   case D:
  >   REG1 = REG1 + INC; *REG1  => REG1 = REG1; *++REG1
  >   
  >   case E:
  >   REG2 = REG1 + INC; *REG1  => *++REG1; REG2 = REG1
  >   where REG1 dies in the last memref and REG2 is not used between 
  >   the add insn and last memref.
  > 
  >   case F:
  >   *REG1; *(REG1 + INC)      =>  *REG1; *++REG1
  >   where REG1 dies in the last memref.
  > 
  >   This latter case is useful for DSP architectures which can handle
  >   multiple autoincrement addresses better than multiple indirect
  >   addresses.  This case could be handled by a separate, optional, scan
  >   of the register ref list.
  > 
  > 
  >   Note that strength_reduce in loop.c performs the following
  >   transformation which we try to undo:
  >   *R; R = R + 1; *R; R = R + 1  => *R; *(R + 1); R = R + 2
  > 
  >   However, the following is not transformed:
  >   R = R + 1; *R; R = R + 1; *R 

This looks very similar to something Cygnus did for a customer but hasn't
had the time to contribute.

Our implementation sat inside regmove and I believe performed similar
transformations.

What I would like to do is have a "cook off" between the two implementations.
ie, I want us to evaluate the two hunks of code both from a standpoint of which
is more effective at optimizing sequences that can use autoinc to remove
instructions and from a cleanliness/long term maintainability standpoint.

I do _not_ want to ultimately have two hunks of code that basically do the
same thing.  That's dumb.


Joern -- can you get a patch for the regmove changes put together and submit
it to the list?

Michael -- can you look at Joern's implementation and compare it to your own?

Joern -- can you do the same with Michael's implementation?


It would be nice if some other folks could try these two implementations on
targets that have autoincrement addresses to see what effect they have.


The two key issues are which optimizes better and which is more maintainable
long term.

jeff


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