This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
opt/7520, try 2
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 27 Sep 2002 14:40:27 -0700
- Subject: 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;
+ }