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]

Whee, micro-optimization



Yes, this is a lame example, but I think it does clearly indicate a problem :-)

float a, b;

blah ()
{
  a = 0.0
  if (b)
    return;
  b = a;
}

Compile with -O2 for a target which does not have floating point hardware.

The "if (b) ..." will generate a call to the FP library.  That call is marked
as constant.

You would think that CSE & cprop would optimize away the load of "a" after
the "if (b) ..." statement since we already know what value will be in "a".
But nooooo, we get a load from a, then a store into b.  How lame.

It turns out we CSE is incorrectly flushing everything it knows about memory
references, even when we hit a constant call.  Opps.

In cse.c, you'll see code like this in a couple places.

  if (GET_CODE (insn) == CALL_INSN)
    {
      if (! CONST_CALL_P (insn))
        invalidate_memory ();
      invalidate_for_call ();
    }

Which makes perfect sense.  If it's not a constant call, then it might write
memory and we have to invalidate memory references.  invalidate_for_call is
supposed invalidate hard registers that are clobbered by the call.

Unfortunately, invalidate_for_call is wiping all memory references out of the
hash table.  That's not right.

For memory referneces which use hard registers in their addresses, we will
bump REG_TICK for the hard register, which invalidates the memory reference
without actually removing it from the table.

Anyway, here's the trivial fix to no longer pessimize memory references around
constant calls.

        * cse.c (invalidate_for_call): Do not remove memory references from
        the table here.  It's handled elsewhere.

Index: cse.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cse.c,v
retrieving revision 1.97
diff -c -3 -p -r1.97 cse.c
*** cse.c	1999/10/15 08:19:37	1.97
--- cse.c	1999/10/18 23:00:57
*************** invalidate_for_call ()
*** 2009,2020 ****
  	{
  	  next = p->next_same_hash;
  
- 	  if (p->in_memory)
- 	    {
- 	      remove_from_table (p, hash);
- 	      continue;
- 	    }
- 
  	  if (GET_CODE (p->exp) != REG
  	      || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER)
  	    continue;
--- 2009,2014 ----



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