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]
Other format: [Raw text]

[patch] for PR26316


Hello,

loop-invariant.c assumes that mem with MEM_NOTRAP_P cannot trap, and
that it therefore can move them out of loop.  However, MEM_NOTRAP_P
is also being set for memory references of type

if (is_in_bounds (i))
  use (a[i])

(in expanders for switches, and possibly on other places), that cannot
trap in their current position, but that may trap if they are moved out
of their conditional context.  We therefore cannot rely on MEM_NOTRAP_P
and we may only move such memory references if they are always reached.

This patch creates a new variant of may_trap_p that is suitable for use
in code motion optimizations, and makes loop-invariant use it.

Bootstrapped & regtested on x86_64.

Zdenek

	PR rtl-optimization/26316
	* rtlanal.c (enum may_trap_p_flags): New.
	(may_trap_p_1): Take flags instead of unaligned_mems argument.  Ignore
	MEM_NOTRAP_P if flags & MTP_AFTER_MOVE.
	(may_trap_p, may_trap_or_fault_p): Pass flags to may_trap_p_1.
	(may_trap_after_code_motion_p): New function.
	* loop-invariant.c (find_identical_invariants): Fix dump formating.
	(find_invariant_insn): Use may_trap_after_code_motion_p.
	* rtl.h (may_trap_after_code_motion_p): Declare.

Index: rtlanal.c
===================================================================
*** rtlanal.c	(revision 111138)
--- rtlanal.c	(working copy)
*************** side_effects_p (rtx x)
*** 2033,2048 ****
    return 0;
  }
  
! /* Return nonzero if evaluating rtx X might cause a trap.  UNALIGNED_MEMS
!    controls whether nonzero is returned for unaligned memory accesses on
!    strict alignment machines.  */
  
  static int
! may_trap_p_1 (rtx x, bool unaligned_mems)
  {
    int i;
    enum rtx_code code;
    const char *fmt;
  
    if (x == 0)
      return 0;
--- 2033,2057 ----
    return 0;
  }
  
! enum may_trap_p_flags
! {
!   MTP_UNALIGNED_MEMS = 1,
!   MTP_AFTER_MOVE = 2
! };
! /* Return nonzero if evaluating rtx X might cause a trap.
!    (FLAGS & MTP_UNALIGNED_MEMS) controls whether nonzero is returned for
!    unaligned memory accesses on strict alignment machines.  If
!    (FLAGS & AFTER_MOVE) is true, returns nonzero even in case the expression
!    cannot trap at its current location, but it might become trapping if moved
!    elsewhere.  */
  
  static int
! may_trap_p_1 (rtx x, unsigned flags)
  {
    int i;
    enum rtx_code code;
    const char *fmt;
+   bool unaligned_mems = (flags & MTP_UNALIGNED_MEMS) != 0;
  
    if (x == 0)
      return 0;
*************** may_trap_p_1 (rtx x, bool unaligned_mems
*** 2072,2078 ****
  
        /* Memory ref can trap unless it's a static var or a stack slot.  */
      case MEM:
!       if (MEM_NOTRAP_P (x)
  	  && (!STRICT_ALIGNMENT || !unaligned_mems))
  	return 0;
        return
--- 2081,2091 ----
  
        /* Memory ref can trap unless it's a static var or a stack slot.  */
      case MEM:
!       if (/* MEM_NOTRAP_P only relates to the actual position of the memory
! 	     reference; moving it out of condition might cause its address
! 	     become invalid.  */
! 	  !(flags & MTP_AFTER_MOVE)
! 	  && MEM_NOTRAP_P (x)
  	  && (!STRICT_ALIGNMENT || !unaligned_mems))
  	return 0;
        return
*************** may_trap_p_1 (rtx x, bool unaligned_mems
*** 2152,2165 ****
      {
        if (fmt[i] == 'e')
  	{
! 	  if (may_trap_p_1 (XEXP (x, i), unaligned_mems))
  	    return 1;
  	}
        else if (fmt[i] == 'E')
  	{
  	  int j;
  	  for (j = 0; j < XVECLEN (x, i); j++)
! 	    if (may_trap_p_1 (XVECEXP (x, i, j), unaligned_mems))
  	      return 1;
  	}
      }
--- 2165,2178 ----
      {
        if (fmt[i] == 'e')
  	{
! 	  if (may_trap_p_1 (XEXP (x, i), flags))
  	    return 1;
  	}
        else if (fmt[i] == 'E')
  	{
  	  int j;
  	  for (j = 0; j < XVECLEN (x, i); j++)
! 	    if (may_trap_p_1 (XVECEXP (x, i, j), flags))
  	      return 1;
  	}
      }
*************** may_trap_p_1 (rtx x, bool unaligned_mems
*** 2171,2177 ****
  int
  may_trap_p (rtx x)
  {
!   return may_trap_p_1 (x, false);
  }
  
  /* Same as above, but additionally return non-zero if evaluating rtx X might
--- 2184,2199 ----
  int
  may_trap_p (rtx x)
  {
!   return may_trap_p_1 (x, 0);
! }
! 
! /* Return nonzero if evaluating rtx X might cause a trap, when the expression
!    is moved from its current location by some optimization.  */
! 
! int
! may_trap_after_code_motion_p (rtx x)
! {
!   return may_trap_p_1 (x, MTP_AFTER_MOVE);
  }
  
  /* Same as above, but additionally return non-zero if evaluating rtx X might
*************** may_trap_p (rtx x)
*** 2217,2223 ****
  int
  may_trap_or_fault_p (rtx x)
  {
!   return may_trap_p_1 (x, true);
  }
  
  /* Return nonzero if X contains a comparison that is not either EQ or NE,
--- 2239,2245 ----
  int
  may_trap_or_fault_p (rtx x)
  {
!   return may_trap_p_1 (x, MTP_UNALIGNED_MEMS);
  }
  
  /* Return nonzero if X contains a comparison that is not either EQ or NE,
Index: loop-invariant.c
===================================================================
*** loop-invariant.c	(revision 111141)
--- loop-invariant.c	(working copy)
*************** find_identical_invariants (htab_t eq, st
*** 479,485 ****
  
    if (dump_file && inv->eqto != inv->invno)
      fprintf (dump_file,
! 	     "Invariant %d is equivalent to invariant %d.\n ",
  	     inv->invno, inv->eqto);
  }
  
--- 479,485 ----
  
    if (dump_file && inv->eqto != inv->invno)
      fprintf (dump_file,
! 	     "Invariant %d is equivalent to invariant %d.\n",
  	     inv->invno, inv->eqto);
  }
  
*************** find_invariant_insn (rtx insn, bool alwa
*** 775,781 ****
      return;
  
    /* We cannot make trapping insn executed, unless it was executed before.  */
!   if (may_trap_p (PATTERN (insn)) && !always_reached)
      return;
  
    depends_on = BITMAP_ALLOC (NULL);
--- 775,781 ----
      return;
  
    /* We cannot make trapping insn executed, unless it was executed before.  */
!   if (may_trap_after_code_motion_p (PATTERN (insn)) && !always_reached)
      return;
  
    depends_on = BITMAP_ALLOC (NULL);
Index: rtl.h
===================================================================
*** rtl.h	(revision 111138)
--- rtl.h	(working copy)
*************** extern int side_effects_p (rtx);
*** 1630,1635 ****
--- 1630,1636 ----
  extern int volatile_refs_p (rtx);
  extern int volatile_insn_p (rtx);
  extern int may_trap_p (rtx);
+ extern int may_trap_after_code_motion_p (rtx);
  extern int may_trap_or_fault_p (rtx);
  extern int inequality_comparisons_p (rtx);
  extern rtx replace_rtx (rtx, rtx, rtx);


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