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]

proposed patch for gcse.c (delete_null_pointer_checks)


Here is a patch I would like applied to gcse.c.
In delete_null_pointer_checks() a pointer is deduced to be non-zero
when it is dereferenced with "p[0]".
This patch also deduces this for small offsets such as "p[1]".

A bootstrapped 19991025 gcc deletes 59 tests
thanks to the current delete_null_pointer_checks() code.
With the patch it deletes 116 more, such as these in gcse.c:
              while (BLOCK_NUM (occr->insn) != dominated && occr)
                occr = occr->next;

              /* Should never happen.  */
              if (!occr)
                abort ();
The "&& occr", and the "if...abort();", are deleted.
The current delete_null_pointer_checks() misses these only
because "occr->insn" is the second (not the first) member of occr.

The patch has an arbitrary limit of 8192 bytes for the offset.
I am not sure any limit is actually needed,
but am worried that an absolute integer address
such as "((int *)0xf0000)[i]" might somehow cause
gcc to erroneously deduce that "i" is non-zero.
On a large collection of source code, the vanilla gcc deleted
509 tests, a version with a limit of 1024 deleted 3536 tests,
and the patch (8192) version deleted 3828.  Diminishing returns.

There is an oddity in the current code (and retained in the patch).
The first (memory load) case limits itself to "pseudo registers".
The second (memory store) case does not.  Huh?

*** gcse.c.orig	Mon Oct 25 22:22:31 1999
--- gcse.c	Wed Oct 27 12:33:35 1999
***************
*** 5037,5047 ****
  	  /* See if we've got a useable memory load.  We handle it first
  	     in case it uses its address register as a dest (which kills
  	     the nonnull property).  */
! 	  if (GET_CODE (SET_SRC (set)) == MEM
! 	      && GET_CODE (XEXP (SET_SRC (set), 0)) == REG
! 	      && REGNO (XEXP (SET_SRC (set), 0)) >= FIRST_PSEUDO_REGISTER)
! 	    SET_BIT (nonnull_local[current_block],
! 		     REGNO (XEXP (SET_SRC (set), 0)));
  
  	  /* Now invalidate stuff clobbered by this insn.  */
  	  note_stores (PATTERN (insn), invalidate_nonnull_info);
--- 5037,5053 ----
  	  /* See if we've got a useable memory load.  We handle it first
  	     in case it uses its address register as a dest (which kills
  	     the nonnull property).  */
! 	  if (GET_CODE (SET_SRC (set)) == MEM)
! 	    {
! 	      rtx addr = XEXP (SET_SRC (set), 0);
! 	      if (GET_CODE (addr) == PLUS
! 		  && GET_CODE (XEXP (addr, 1)) == CONST_INT
! 		  && (unsigned HOST_WIDE_INT) INTVAL (XEXP (addr, 1)) < 8192)
! 		addr = XEXP (addr, 0);
! 	      if (GET_CODE (addr) == REG
! 		  && REGNO (addr) >= FIRST_PSEUDO_REGISTER)
! 		SET_BIT (nonnull_local[current_block], REGNO (addr));
! 	    }
  
  	  /* Now invalidate stuff clobbered by this insn.  */
  	  note_stores (PATTERN (insn), invalidate_nonnull_info);
***************
*** 5049,5058 ****
  	  /* And handle stores, we do these last since any sets in INSN can
  	     not kill the nonnull property if it is derived from a MEM
  	     appearing in a SET_DEST.  */
! 	  if (GET_CODE (SET_DEST (set)) == MEM
! 	      && GET_CODE (XEXP (SET_DEST (set), 0)) == REG)
! 	    SET_BIT (nonnull_local[current_block],
! 		     REGNO (XEXP (SET_DEST (set), 0)));
  	}
      }
  
--- 5055,5070 ----
  	  /* And handle stores, we do these last since any sets in INSN can
  	     not kill the nonnull property if it is derived from a MEM
  	     appearing in a SET_DEST.  */
! 	  if (GET_CODE (SET_DEST (set)) == MEM)
! 	    {
! 	      rtx addr = XEXP (SET_DEST (set), 0);
! 	      if (GET_CODE (addr) == PLUS
! 		  && GET_CODE (XEXP (addr, 1)) == CONST_INT
! 		  && (unsigned HOST_WIDE_INT) INTVAL (XEXP (addr, 1)) < 8192)
! 		addr = XEXP (addr, 0);
! 	      if (GET_CODE (addr) == REG)
! 		SET_BIT (nonnull_local[current_block], REGNO (addr));
! 	    }
  	}
      }
  


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