From: Andrey Belevantsev Date: Tue, 24 Aug 2010 09:02:30 +0000 (+0400) Subject: backport: re PR rtl-optimization/42389 (ICE in advance_state_on_fence with sel-schd... X-Git-Tag: releases/gcc-4.4.5~115 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7bb3593c938642705b7b9496607087e14b52b782;p=thirdparty%2Fgcc.git backport: re PR rtl-optimization/42389 (ICE in advance_state_on_fence with sel-schd for 175.vpr) Backport from mainline: PR rtl-optimization/42389 * sel-sched.c (advance_one_cycle): Set FENCE_ISSUE_MORE to can_issue_more. (advance_state_on_fence): Likewise. (sel_target_adjust_priority): Print debug output only when sched_verbose >= 4, not 2. (get_expr_cost): Do not issue all unique insns on the next cycle. (fill_insns): Initialize can_issue_more from the value saved with the fence. * sel-sched-ir.c (flist_add): New parameter issue_more. Init FENCE_ISSUE_MORE with it. (merge_fences): Likewise. (init_fences): Update call to flist_add. (add_to_fences, add_clean_fence_to_fences) (add_dirty_fence_to_fences): Likewise. (move_fence_to_fences): Update call to merge_fences. (invoke_reorder_hooks): Do not reset can_issue_more on insns from sched groups. * sel-sched-ir.h (struct _fence): New field issue_more. (FENCE_ISSUE_MORE): New accessor macro. From-SVN: r163508 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b7be6f0394ea..b22ce56160a6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,30 @@ +2010-08-24 Andrey Belevantsev + + Backport from mainline: + 2010-01-14 Andrey Belevantsev + Alexander Monakov + + PR rtl-optimization/42389 + * sel-sched.c (advance_one_cycle): Set FENCE_ISSUE_MORE + to can_issue_more. + (advance_state_on_fence): Likewise. + (sel_target_adjust_priority): Print debug output only when + sched_verbose >= 4, not 2. + (get_expr_cost): Do not issue all unique insns on the next cycle. + (fill_insns): Initialize can_issue_more from the value saved + with the fence. + * sel-sched-ir.c (flist_add): New parameter issue_more. + Init FENCE_ISSUE_MORE with it. + (merge_fences): Likewise. + (init_fences): Update call to flist_add. + (add_to_fences, add_clean_fence_to_fences) + (add_dirty_fence_to_fences): Likewise. + (move_fence_to_fences): Update call to merge_fences. + (invoke_reorder_hooks): Do not reset can_issue_more on insns from + sched groups. + * sel-sched-ir.h (struct _fence): New field issue_more. + (FENCE_ISSUE_MORE): New accessor macro. + 2010-08-24 Andrey Belevantsev Backport from mainline: diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c index b80430718232..aa479f9cc840 100644 --- a/gcc/sel-sched-ir.c +++ b/gcc/sel-sched-ir.c @@ -258,10 +258,10 @@ init_fence_for_scheduling (fence_t f) /* Add new fence consisting of INSN and STATE to the list pointed to by LP. */ static void -flist_add (flist_t *lp, insn_t insn, state_t state, deps_t dc, void *tc, - insn_t last_scheduled_insn, VEC(rtx,gc) *executing_insns, - int *ready_ticks, int ready_ticks_size, insn_t sched_next, - int cycle, int cycle_issued_insns, +flist_add (flist_t *lp, insn_t insn, state_t state, deps_t dc, void *tc, + insn_t last_scheduled_insn, VEC(rtx,gc) *executing_insns, + int *ready_ticks, int ready_ticks_size, insn_t sched_next, + int cycle, int cycle_issued_insns, int issue_more, bool starts_cycle_p, bool after_stall_p) { fence_t f; @@ -286,6 +286,7 @@ flist_add (flist_t *lp, insn_t insn, state_t state, deps_t dc, void *tc, FENCE_TC (f) = tc; FENCE_LAST_SCHEDULED_INSN (f) = last_scheduled_insn; + FENCE_ISSUE_MORE (f) = issue_more; FENCE_EXECUTING_INSNS (f) = executing_insns; FENCE_READY_TICKS (f) = ready_ticks; FENCE_READY_TICKS_SIZE (f) = ready_ticks_size; @@ -616,8 +617,9 @@ init_fences (insn_t old_fence) XCNEWVEC (int, ready_ticks_size), /* ready_ticks */ ready_ticks_size, NULL_RTX /* sched_next */, - 1 /* cycle */, 0 /* cycle_issued_insns */, - 1 /* starts_cycle_p */, 0 /* after_stall_p */); + 1 /* cycle */, 0 /* cycle_issued_insns */, + issue_rate, /* issue_more */ + 1 /* starts_cycle_p */, 0 /* after_stall_p */); } } @@ -627,15 +629,15 @@ init_fences (insn_t old_fence) 2) deps context and cycle is propagated from more probable edge; 3) all other fields are set to corresponding constant values. - INSN, STATE, DC, TC, LAST_SCHEDULED_INSN, EXECUTING_INSNS, - READY_TICKS, READY_TICKS_SIZE, SCHED_NEXT, CYCLE and AFTER_STALL_P - are the corresponding fields of the second fence. */ + INSN, STATE, DC, TC, LAST_SCHEDULED_INSN, EXECUTING_INSNS, + READY_TICKS, READY_TICKS_SIZE, SCHED_NEXT, CYCLE, ISSUE_MORE + and AFTER_STALL_P are the corresponding fields of the second fence. */ static void merge_fences (fence_t f, insn_t insn, state_t state, deps_t dc, void *tc, rtx last_scheduled_insn, VEC(rtx, gc) *executing_insns, int *ready_ticks, int ready_ticks_size, - rtx sched_next, int cycle, bool after_stall_p) + rtx sched_next, int cycle, int issue_more, bool after_stall_p) { insn_t last_scheduled_insn_old = FENCE_LAST_SCHEDULED_INSN (f); @@ -665,6 +667,7 @@ merge_fences (fence_t f, insn_t insn, FENCE_CYCLE (f) = cycle; FENCE_LAST_SCHEDULED_INSN (f) = NULL; + FENCE_ISSUE_MORE (f) = issue_rate; VEC_free (rtx, gc, executing_insns); free (ready_ticks); if (FENCE_EXECUTING_INSNS (f)) @@ -696,6 +699,7 @@ merge_fences (fence_t f, insn_t insn, delete_target_context (tc); FENCE_LAST_SCHEDULED_INSN (f) = NULL; + FENCE_ISSUE_MORE (f) = issue_rate; } else if (candidate->src == BLOCK_FOR_INSN (last_scheduled_insn)) @@ -712,6 +716,7 @@ merge_fences (fence_t f, insn_t insn, FENCE_TC (f) = tc; FENCE_LAST_SCHEDULED_INSN (f) = last_scheduled_insn; + FENCE_ISSUE_MORE (f) = issue_more; } else { @@ -795,10 +800,11 @@ merge_fences (fence_t f, insn_t insn, other parameters. */ static void add_to_fences (flist_tail_t new_fences, insn_t insn, - state_t state, deps_t dc, void *tc, rtx last_scheduled_insn, - VEC(rtx, gc) *executing_insns, int *ready_ticks, - int ready_ticks_size, rtx sched_next, int cycle, - int cycle_issued_insns, bool starts_cycle_p, bool after_stall_p) + state_t state, deps_t dc, void *tc, rtx last_scheduled_insn, + VEC(rtx, gc) *executing_insns, int *ready_ticks, + int ready_ticks_size, rtx sched_next, int cycle, + int cycle_issued_insns, int issue_rate, + bool starts_cycle_p, bool after_stall_p) { fence_t f = flist_lookup (FLIST_TAIL_HEAD (new_fences), insn); @@ -807,16 +813,16 @@ add_to_fences (flist_tail_t new_fences, insn_t insn, flist_add (FLIST_TAIL_TAILP (new_fences), insn, state, dc, tc, last_scheduled_insn, executing_insns, ready_ticks, ready_ticks_size, sched_next, cycle, cycle_issued_insns, - starts_cycle_p, after_stall_p); + issue_rate, starts_cycle_p, after_stall_p); FLIST_TAIL_TAILP (new_fences) = &FLIST_NEXT (*FLIST_TAIL_TAILP (new_fences)); } else { - merge_fences (f, insn, state, dc, tc, last_scheduled_insn, - executing_insns, ready_ticks, ready_ticks_size, - sched_next, cycle, after_stall_p); + merge_fences (f, insn, state, dc, tc, last_scheduled_insn, + executing_insns, ready_ticks, ready_ticks_size, + sched_next, cycle, issue_rate, after_stall_p); } } @@ -835,7 +841,7 @@ move_fence_to_fences (flist_t old_fences, flist_tail_t new_fences) merge_fences (f, old->insn, old->state, old->dc, old->tc, old->last_scheduled_insn, old->executing_insns, old->ready_ticks, old->ready_ticks_size, - old->sched_next, old->cycle, + old->sched_next, old->cycle, old->issue_more, old->after_stall_p); } else @@ -861,7 +867,7 @@ add_clean_fence_to_fences (flist_tail_t new_fences, insn_t succ, fence_t fence) NULL_RTX, NULL, XCNEWVEC (int, ready_ticks_size), ready_ticks_size, NULL_RTX, FENCE_CYCLE (fence) + 1, - 0, 1, FENCE_AFTER_STALL_P (fence)); + 0, issue_rate, 1, FENCE_AFTER_STALL_P (fence)); } /* Add a new fence to NEW_FENCES list and initialize all of its data @@ -885,6 +891,7 @@ add_dirty_fence_to_fences (flist_tail_t new_fences, insn_t succ, fence_t fence) FENCE_SCHED_NEXT (fence), FENCE_CYCLE (fence), FENCE_ISSUED_INSNS (fence), + FENCE_ISSUE_MORE (fence), FENCE_STARTS_CYCLE_P (fence), FENCE_AFTER_STALL_P (fence)); } diff --git a/gcc/sel-sched-ir.h b/gcc/sel-sched-ir.h index 335ed0ac3006..4e7da57d8d59 100644 --- a/gcc/sel-sched-ir.h +++ b/gcc/sel-sched-ir.h @@ -296,6 +296,9 @@ struct _fence /* Insn, which has been scheduled last on this fence. */ rtx last_scheduled_insn; + /* The last value of can_issue_more variable on this fence. */ + int issue_more; + /* If non-NULL force the next scheduled insn to be SCHED_NEXT. */ rtx sched_next; @@ -325,6 +328,7 @@ typedef struct _fence *fence_t; #define FENCE_DC(F) ((F)->dc) #define FENCE_TC(F) ((F)->tc) #define FENCE_LAST_SCHEDULED_INSN(F) ((F)->last_scheduled_insn) +#define FENCE_ISSUE_MORE(F) ((F)->issue_more) #define FENCE_EXECUTING_INSNS(F) ((F)->executing_insns) #define FENCE_READY_TICKS(F) ((F)->ready_ticks) #define FENCE_READY_TICKS_SIZE(F) ((F)->ready_ticks_size) diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c index f053a2d230c0..9ca2ec435224 100644 --- a/gcc/sel-sched.c +++ b/gcc/sel-sched.c @@ -587,6 +587,7 @@ advance_one_cycle (fence_t fence) FENCE_ISSUED_INSNS (fence) = 0; FENCE_STARTS_CYCLE_P (fence) = 1; can_issue_more = issue_rate; + FENCE_ISSUE_MORE (fence) = can_issue_more; for (i = 0; VEC_iterate (rtx, FENCE_EXECUTING_INSNS (fence), i, insn); ) { @@ -3235,9 +3236,9 @@ sel_target_adjust_priority (expr_t expr) gcc_assert (EXPR_PRIORITY_ADJ (expr) >= 0); - if (sched_verbose >= 2) - sel_print ("sel_target_adjust_priority: insn %d, %d +%d = %d.\n", - INSN_UID (EXPR_INSN_RTX (expr)), EXPR_PRIORITY (expr), + if (sched_verbose >= 4) + sel_print ("sel_target_adjust_priority: insn %d, %d+%d = %d.\n", + INSN_UID (EXPR_INSN_RTX (expr)), EXPR_PRIORITY (expr), EXPR_PRIORITY_ADJ (expr), new_priority); return new_priority; @@ -4033,8 +4034,8 @@ invoke_reorder_hooks (fence_t fence) ran_hook = true; } - else - issue_more = issue_rate; + else + issue_more = FENCE_ISSUE_MORE (fence); /* Ensure that ready list and vec_av_set are in line with each other, i.e. vec_av_set[i] == ready_element (&ready, i). */ @@ -4224,9 +4225,7 @@ get_expr_cost (expr_t expr, fence_t fence) if (recog_memoized (insn) < 0) { - if (!FENCE_STARTS_CYCLE_P (fence) - /* FIXME: Is this condition necessary? */ - && VINSN_UNIQUE_P (EXPR_VINSN (expr)) + if (!FENCE_STARTS_CYCLE_P (fence) && INSN_ASM_P (insn)) /* This is asm insn which is tryed to be issued on the cycle not first. Issue it on the next cycle. */ @@ -5065,6 +5064,7 @@ advance_state_on_fence (fence_t fence, insn_t insn) if (sched_verbose >= 2) debug_state (FENCE_STATE (fence)); FENCE_STARTS_CYCLE_P (fence) = 0; + FENCE_ISSUE_MORE (fence) = can_issue_more; return asm_p; } @@ -5246,6 +5246,7 @@ fill_insns (fence_t fence, int seqno, ilist_t **scheduled_insns_tailpp) blist_add (&bnds, insn, NULL, FENCE_DC (fence)); bnds_tailp = &BLIST_NEXT (bnds); set_target_context (FENCE_TC (fence)); + can_issue_more = FENCE_ISSUE_MORE (fence); target_bb = INSN_BB (insn); /* Do while we can add any operation to the current group. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0800e582673f..d50db3bb69ed 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2010-08-24 Andrey Belevantsev + + Backport from mainline: + 2010-01-14 Alexander Monakov + + PR rtl-optimization/42389 + * gcc.dg/pr42389.c: New. + 2010-08-24 Andrey Belevantsev Backport from mainline: diff --git a/gcc/testsuite/gcc.dg/pr42389.c b/gcc/testsuite/gcc.dg/pr42389.c new file mode 100644 index 000000000000..2c1d98145a74 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr42389.c @@ -0,0 +1,87 @@ +/* { dg-do compile { target powerpc*-*-* ia64-*-* x86_64-*-* } } */ +/* { dg-options "-O2 -fselective-scheduling -fsel-sched-pipelining" } */ + +struct s_linked_f_pointer +{ + struct s_linked_f_pointer *next; + float *fptr; +}; +struct s_trace +{ + int index; +}; +struct s_rr_cost +{ + float base_cost; + float acc_cost; +}; +extern int num_nets; +extern struct s_trace **trace_head; +extern struct s_rr_cost *rr_cost; +struct s_rr_route +{ + float cost; +}; +static int heap_tail; +extern struct s_linked_f_pointer *rr_modified_head; +extern struct s_rr_route *rr_route; + +void +empty_heap (void) +{ + heap_tail = 1; +} + +void +reset_path_costs (void) +{ + struct s_linked_f_pointer *mod_ptr; + if (rr_modified_head != ((void *) 0)) + { + mod_ptr = rr_modified_head; + while (mod_ptr->next != ((void *) 0)) + { + *(mod_ptr->fptr) = 1.e30; + mod_ptr = mod_ptr->next; + } + rr_modified_head = ((void *) 0); + } +} + +static void +route_net (int inet) +{ + int i; + for (i = 1; i < inet; i++) + reset_path_costs (); + empty_heap (); + reset_path_costs (); +} + +void +pathfinder_update_one_cost (int inet, float pres_fac, float acc_fac) +{ + struct s_trace *tptr; + int inode = 0; + + tptr = trace_head[inet]; + inode = tptr->index; + rr_route[inode].cost = rr_cost[inode].base_cost + rr_cost[inode].acc_cost; +} + +int +try_route (int n, float x, float y) +{ + int inet, itry; + float pres_fac; + for (itry = 1; itry <= n; itry++) + { + for (inet = 0; inet < num_nets; inet++) + { + route_net (inet); + pathfinder_update_one_cost (inet, pres_fac, x); + } + pres_fac *= y; + } +} +