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]

opt/7520, try 2


Should avoid the delayed branch scheduling aborts seen on sparc
and hppa yesterday.  Also commits the test case which I'd forgotten.


r~


        * cfganal.c (flow_active_insn_p): New.
        (forwarder_block_p): Use it.

Index: cfganal.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfganal.c,v
retrieving revision 1.27
diff -c -p -d -r1.27 cfganal.c
*** cfganal.c	22 Sep 2002 02:03:15 -0000	1.27
--- cfganal.c	27 Sep 2002 21:37:18 -0000
*************** static void flow_dfs_compute_reverse_fin
*** 54,60 ****
--- 54,84 ----
    PARAMS ((depth_first_search_ds));
  static void remove_fake_successors	PARAMS ((basic_block));
  static bool need_fake_edge_p		PARAMS ((rtx));
+ static bool flow_active_insn_p		PARAMS ((rtx));
  
+ /* Like active_insn_p, except keep the return value clobber around
+    even after reload.  */
+ 
+ static bool
+ flow_active_insn_p (insn)
+      rtx insn;
+ {
+   if (active_insn_p (insn))
+     return true;
+ 
+   /* A clobber of the function return value exists for buggy 
+      programs that fail to return a value.  It's effect is to
+      keep the return value from being live across the entire
+      function.  If we allow it to be skipped, we introduce the
+      possibility for register livetime aborts.  */
+   if (GET_CODE (PATTERN (insn)) == CLOBBER
+       && GET_CODE (XEXP (PATTERN (insn), 0)) == REG
+       && REG_FUNCTION_VALUE_P (XEXP (PATTERN (insn), 0)))
+     return true;
+ 
+   return false;
+ }
+ 
  /* Return true if the block has no effect and only forwards control flow to
     its single destination.  */
  
*************** forwarder_block_p (bb)
*** 69,80 ****
      return false;
  
    for (insn = bb->head; insn != bb->end; insn = NEXT_INSN (insn))
!     if (INSN_P (insn) && active_insn_p (insn))
        return false;
  
    return (!INSN_P (insn)
  	  || (GET_CODE (insn) == JUMP_INSN && simplejump_p (insn))
! 	  || !active_insn_p (insn));
  }
  
  /* Return nonzero if we can reach target from src by falling through.  */
--- 93,104 ----
      return false;
  
    for (insn = bb->head; insn != bb->end; insn = NEXT_INSN (insn))
!     if (INSN_P (insn) && flow_active_insn_p (insn))
        return false;
  
    return (!INSN_P (insn)
  	  || (GET_CODE (insn) == JUMP_INSN && simplejump_p (insn))
! 	  || !flow_active_insn_p (insn));
  }
  
  /* Return nonzero if we can reach target from src by falling through.  */
Index: testsuite/gcc.c-torture/compile/20020927-1.c
===================================================================
RCS file: testsuite/gcc.c-torture/compile/20020927-1.c
diff -N testsuite/gcc.c-torture/compile/20020927-1.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.c-torture/compile/20020927-1.c	27 Sep 2002 21:37:18 -0000
***************
*** 0 ****
--- 1,26 ----
+ /* PR optimization/7520 */
+ /* ICE at -O3 on x86 due to register life problems caused by
+    the return-without-value in bar.  */
+ 
+ int
+ foo ()
+ {
+   int i;
+   long long int j;
+ 
+   while (1)
+     {
+       if (j & 1)
+ 	++i;
+       j >>= 1;
+       if (j)
+ 	return i;
+     }
+ }
+ 
+ int
+ bar ()
+ {
+   if (foo ())
+     return;
+ }


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