This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH]: Fix PR28489 - [4.2 Regression] ICE: in move_block_after_check, at haifa-sched.c:4337
- From: Maxim Kuvyrkov <mkuvyrkov at ispras dot ru>
- To: Vladimir Makarov <vmakarov at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org, Martin Michlmayr <tbm at cyrius dot com>, sje at cup dot hp dot com, fang at csl dot cornell dot edu
- Date: Sun, 24 Sep 2006 14:11:29 +0400
- Subject: [PATCH]: Fix PR28489 - [4.2 Regression] ICE: in move_block_after_check, at haifa-sched.c:4337
Hi!
The first patch fixes PR29128 and the second one provides cleanup for
the related code.
The PR appears in the code that handles interblock movements of the
jumps in sched-ebb.c . Actually, the only jumps we will possibly move
during sched-ebb are 'branchy speculation checks'. So the problem is
that all 'speculation checks' were considered as jumps in sched-ebb.c:
advance_target_bb ().
For clarity, second patch introduces macros to identify speculation checks.
Both patches were bootstrapped and regtested on {ia64, i386}-linux-gnu.
I also checked that the patched compiler produces exactly the same
SPEC2000 binaries as the original one.
Thanks,
Maxim
2006-09-23 Maxim Kuvyrkov <mkuvyrkov@ispras.ru>
PR rtl-optimization/29128
* sched-ebb.c (advance_target_bb): Use correct condition to
allow interblock movement of speculation checks.
* sched-int.h (IS_SPEC_BRANCY_CHECK_P): New macro.
2006-09-23 Maxim Kuvyrkov <mkuvyrkov@ispras.ru>
PR rtl-optimization/29128
* gcc.c-torture/compile/pr29128.c: New test.
--- sched-ebb.c (/local/trunk/gcc) (revision 278)
+++ sched-ebb.c (/local/fix-pr29128/gcc) (revision 278)
@@ -719,9 +719,13 @@ advance_target_bb (basic_block bb, rtx i
{
if (BLOCK_FOR_INSN (insn) != bb
&& control_flow_insn_p (insn)
- && !RECOVERY_BLOCK (insn)
- && !RECOVERY_BLOCK (BB_END (bb)))
+ /* We handle interblock movement of the speculation check
+ or over a speculation check in
+ haifa-sched.c: move_block_after_check (). */
+ && !IS_SPEC_BRANCHY_CHECK_P (insn)
+ && !IS_SPEC_BRANCHY_CHECK_P (BB_END (bb)))
{
+ /* Assert that we don't move jumps across blocks. */
gcc_assert (!control_flow_insn_p (BB_END (bb))
&& NOTE_INSN_BASIC_BLOCK_P (BB_HEAD (bb->next_bb)));
return bb;
--- testsuite/gcc.c-torture/compile/pr29128.c (/local/trunk/gcc) (revision 278)
+++ testsuite/gcc.c-torture/compile/pr29128.c (/local/fix-pr29128/gcc) (revision 278)
@@ -0,0 +1,28 @@
+typedef unsigned long Eterm;
+process_main (void)
+{
+ register Eterm x0;
+ register Eterm *reg = ((void *) 0);
+ register Eterm *I = ((void *) 0);
+ static void *opcodes[] = {
+ &&lb_allocate_heap_zero_III,
+ &&lb_allocate_init_tIy, &&lb_allocate_zero_tt
+ };
+lb_allocate_heap_III:{
+ Eterm *next;
+ goto *(next);
+ }
+lb_allocate_heap_zero_III:{
+ }
+lb_allocate_init_tIy:{
+ }
+lb_allocate_zero_tt:{
+ Eterm *next;
+ {
+ Eterm *tmp_ptr = ((Eterm *) (((x0)) - 0x1));
+ (*(Eterm *) (((unsigned char *) reg) + (I[(0) + 1]))) = ((tmp_ptr)[0]);
+ x0 = ((tmp_ptr)[1]);
+ }
+ goto *(next);
+ }
+}
--- sched-int.h (/local/trunk/gcc) (revision 278)
+++ sched-int.h (/local/fix-pr29128/gcc) (revision 278)
@@ -359,6 +359,9 @@ extern regset *glat_start, *glat_end;
#define RECOVERY_BLOCK(INSN) (h_i_d[INSN_UID (INSN)].recovery_block)
#define ORIG_PAT(INSN) (h_i_d[INSN_UID (INSN)].orig_pat)
+#define IS_SPEC_BRANCHY_CHECK_P(INSN) \
+ (RECOVERY_BLOCK (INSN) != NULL && RECOVERY_BLOCK (INSN) != EXIT_BLOCK_PTR)
+
/* DEP_STATUS of the link encapsulates information, that is needed for
speculative scheduling. Namely, it is 4 integers in the range
[0, MAX_DEP_WEAK] and 3 bits.
2006-09-24 Maxim Kuvyrkov <mkuvyrkov@ispras.ru>
* sched-int.h (IS_SPEC_CHECK_P, IS_SPEC_SIMPLE_CHECK_P): New macros.
* sched-ebb.c (begin_schedule_ready): Use them.
* haifa-sched.c (schedule_insn, move_insn, try_ready,
add_to_speculative_block, create_check_block_twin, speculate_insn,
fix_jump_move, move_block_after_check): Ditto.
* sched-rgn.c (new_ready): Ditto.
--- sched-ebb.c (/local/fix-pr29128/gcc) (revision 279)
+++ sched-ebb.c (/local/fix-pr29128-1/gcc) (revision 279)
@@ -145,7 +145,7 @@ begin_schedule_ready (rtx insn, rtx last
gcc_assert (!e || !(e->flags & EDGE_COMPLEX));
gcc_assert (BLOCK_FOR_INSN (insn) == last_bb
- && !RECOVERY_BLOCK (insn)
+ && !IS_SPEC_CHECK_P (insn)
&& BB_HEAD (last_bb) != insn
&& BB_END (last_bb) == insn);
--- haifa-sched.c (/local/fix-pr29128/gcc) (revision 279)
+++ haifa-sched.c (/local/fix-pr29128-1/gcc) (revision 279)
@@ -1190,8 +1190,7 @@ schedule_insn (rtx insn)
resolve_dep (next, insn);
- if (!RECOVERY_BLOCK (insn)
- || RECOVERY_BLOCK (insn) == EXIT_BLOCK_PTR)
+ if (!IS_SPEC_BRANCHY_CHECK_P (insn))
{
int effective_cost;
@@ -1960,8 +1959,7 @@ move_insn (rtx insn)
gcc_assert (!jump_p
|| ((current_sched_info->flags & SCHED_RGN)
- && RECOVERY_BLOCK (insn)
- && RECOVERY_BLOCK (insn) != EXIT_BLOCK_PTR)
+ && IS_SPEC_BRANCHY_CHECK_P (insn))
|| (current_sched_info->flags & SCHED_EBB));
gcc_assert (BLOCK_FOR_INSN (PREV_INSN (insn)) == bb);
@@ -3115,8 +3113,7 @@ try_ready (rtx next)
or we simply don't care (*ts & HARD_DEP). */
gcc_assert (!ORIG_PAT (next)
- || !RECOVERY_BLOCK (next)
- || RECOVERY_BLOCK (next) == EXIT_BLOCK_PTR);
+ || !IS_SPEC_BRANCHY_CHECK_P (next));
if (*ts & HARD_DEP)
{
@@ -3128,11 +3125,11 @@ try_ready (rtx next)
change_queue_index (next, QUEUE_NOWHERE);
return -1;
}
- else if (!(*ts & BEGIN_SPEC) && ORIG_PAT (next) && !RECOVERY_BLOCK (next))
+ else if (!(*ts & BEGIN_SPEC) && ORIG_PAT (next) && !IS_SPEC_CHECK_P (next))
/* We should change pattern of every previously speculative
instruction - and we determine if NEXT was speculative by using
- ORIG_PAT field. Except one case - simple checks have ORIG_PAT
- pat too, hence we also check for the RECOVERY_BLOCK. */
+ ORIG_PAT field. Except one case - speculation checks have ORIG_PAT
+ pat too, so skip them. */
{
change_pattern (next, ORIG_PAT (next));
ORIG_PAT (next) = 0;
@@ -3444,7 +3441,7 @@ add_to_speculative_block (rtx insn)
check = XEXP (link, 0);
- if (RECOVERY_BLOCK (check))
+ if (IS_SPEC_SIMPLE_CHECK_P (check))
{
create_check_block_twin (check, true);
link = LOG_LINKS (insn);
@@ -3466,7 +3463,8 @@ add_to_speculative_block (rtx insn)
&& (DEP_STATUS (link) & DEP_TYPES) == DEP_TRUE);
check = XEXP (link, 0);
- gcc_assert (!RECOVERY_BLOCK (check) && !ORIG_PAT (check)
+
+ gcc_assert (!IS_SPEC_CHECK_P (check) && !ORIG_PAT (check)
&& QUEUE_INDEX (check) == QUEUE_NOWHERE);
rec = BLOCK_FOR_INSN (check);
@@ -3718,7 +3716,7 @@ create_check_block_twin (rtx insn, bool
gcc_assert (ORIG_PAT (insn)
&& (!mutate_p
- || (RECOVERY_BLOCK (insn) == EXIT_BLOCK_PTR
+ || (IS_SPEC_SIMPLE_CHECK_P (insn)
&& !(TODO_SPEC (insn) & SPECULATIVE))));
/* Create recovery block. */
@@ -4091,7 +4089,7 @@ speculate_insn (rtx insn, ds_t request,
|| (request & spec_info->mask) != request)
return -1;
- gcc_assert (!RECOVERY_BLOCK (insn));
+ gcc_assert (!IS_SPEC_CHECK_P (insn));
if (request & BE_IN_SPEC)
{
@@ -4299,8 +4297,7 @@ fix_jump_move (rtx jump)
jump_bb_next = jump_bb->next_bb;
gcc_assert (current_sched_info->flags & SCHED_EBB
- || (RECOVERY_BLOCK (jump)
- && RECOVERY_BLOCK (jump) != EXIT_BLOCK_PTR));
+ || IS_SPEC_BRANCHY_CHECK_P (jump));
if (!NOTE_INSN_BASIC_BLOCK_P (BB_END (jump_bb_next)))
/* if jump_bb_next is not empty. */
@@ -4333,8 +4330,8 @@ move_block_after_check (rtx jump)
update_bb_for_insn (jump_bb);
- gcc_assert (RECOVERY_BLOCK (jump)
- || RECOVERY_BLOCK (BB_END (jump_bb_next)));
+ gcc_assert (IS_SPEC_CHECK_P (jump)
+ || IS_SPEC_CHECK_P (BB_END (jump_bb_next)));
unlink_block (jump_bb_next);
link_block (jump_bb_next, bb);
--- sched-int.h (/local/fix-pr29128/gcc) (revision 279)
+++ sched-int.h (/local/fix-pr29128-1/gcc) (revision 279)
@@ -359,6 +359,8 @@ extern regset *glat_start, *glat_end;
#define RECOVERY_BLOCK(INSN) (h_i_d[INSN_UID (INSN)].recovery_block)
#define ORIG_PAT(INSN) (h_i_d[INSN_UID (INSN)].orig_pat)
+#define IS_SPEC_CHECK_P(INSN) (RECOVERY_BLOCK (INSN) != NULL)
+#define IS_SPEC_SIMPLE_CHECK_P(INSN) (RECOVERY_BLOCK (INSN) == EXIT_BLOCK_PTR)
#define IS_SPEC_BRANCHY_CHECK_P(INSN) \
(RECOVERY_BLOCK (INSN) != NULL && RECOVERY_BLOCK (INSN) != EXIT_BLOCK_PTR)
--- sched-rgn.c (/local/fix-pr29128/gcc) (revision 279)
+++ sched-rgn.c (/local/fix-pr29128-1/gcc) (revision 279)
@@ -2089,7 +2089,7 @@ new_ready (rtx next, ds_t ts)
&& ((recog_memoized (next) >= 0
&& min_insn_conflict_delay (curr_state, next, next)
> PARAM_VALUE (PARAM_MAX_SCHED_INSN_CONFLICT_DELAY))
- || RECOVERY_BLOCK (next)
+ || IS_SPEC_CHECK_P (next)
|| !check_live (next, INSN_BB (next))
|| (not_ex_free = !is_exception_free (next, INSN_BB (next),
target_bb)))))