diff options
author | Bernd Schmidt <bernds@codesourcery.com> | 2012-04-11 14:40:48 +0000 |
---|---|---|
committer | Bernd Schmidt <bernds@gcc.gnu.org> | 2012-04-11 14:40:48 +0000 |
commit | 0564160356c4443894fd8151439b7800e808540c (patch) | |
tree | f54a5d51e49dcb0a6c257ee21a4720f3ec45826b /gcc | |
parent | 7861732fe8bf66cc6d0590d410aacee2618b2ffa (diff) | |
download | gcc-0564160356c4443894fd8151439b7800e808540c.zip gcc-0564160356c4443894fd8151439b7800e808540c.tar.gz gcc-0564160356c4443894fd8151439b7800e808540c.tar.bz2 |
haifa-sched.c (prune_ready_list): Rework handling of SCHED_GROUP_P insns so that no other insn is queued for a...
* haifa-sched.c (prune_ready_list): Rework handling of SCHED_GROUP_P
insns so that no other insn is queued for a time before them.
From-SVN: r186325
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/haifa-sched.c | 146 |
2 files changed, 85 insertions, 64 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f1719d8..1f1b2b4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -3,6 +3,9 @@ * sel-sched.c (sel_global_init): Swap order of sched_rgn_init and sched_init calls. + * haifa-sched.c (prune_ready_list): Rework handling of SCHED_GROUP_P + insns so that no other insn is queued for a time before them. + 2012-04-11 Richard Guenther <rguenther@suse.de> PR middle-end/52621 diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c index 09c6af2..569cd2b 100644 --- a/gcc/haifa-sched.c +++ b/gcc/haifa-sched.c @@ -3946,88 +3946,106 @@ static void prune_ready_list (state_t temp_state, bool first_cycle_insn_p, bool shadows_only_p, bool modulo_epilogue_p) { - int i; + int i, pass; bool sched_group_found = false; + int min_cost_group = 1; - restart: for (i = 0; i < ready.n_ready; i++) { rtx insn = ready_element (&ready, i); - int cost = 0; - const char *reason = "resource conflict"; - - if (DEBUG_INSN_P (insn)) - continue; - - if (SCHED_GROUP_P (insn) && !sched_group_found) + if (SCHED_GROUP_P (insn)) { sched_group_found = true; - if (i > 0) - goto restart; + break; } + } - if (sched_group_found && !SCHED_GROUP_P (insn)) - { - cost = 1; - reason = "not in sched group"; - } - else if (modulo_epilogue_p && INSN_EXACT_TICK (insn) == INVALID_TICK) - { - cost = max_insn_queue_index; - reason = "not an epilogue insn"; - } - else if (shadows_only_p && !SHADOW_P (insn)) - { - cost = 1; - reason = "not a shadow"; - } - else if (recog_memoized (insn) < 0) - { - if (!first_cycle_insn_p - && (GET_CODE (PATTERN (insn)) == ASM_INPUT - || asm_noperands (PATTERN (insn)) >= 0)) - cost = 1; - reason = "asm"; - } - else if (sched_pressure_p) - cost = 0; - else + /* Make two passes if there's a SCHED_GROUP_P insn; make sure to handle + such an insn first and note its cost, then schedule all other insns + for one cycle later. */ + for (pass = sched_group_found ? 0 : 1; pass < 2; ) + { + int n = ready.n_ready; + for (i = 0; i < n; i++) { - int delay_cost = 0; + rtx insn = ready_element (&ready, i); + int cost = 0; + const char *reason = "resource conflict"; - if (delay_htab) + if (DEBUG_INSN_P (insn)) + continue; + + if (sched_group_found && !SCHED_GROUP_P (insn)) { - struct delay_pair *delay_entry; - delay_entry - = (struct delay_pair *)htab_find_with_hash (delay_htab, insn, - htab_hash_pointer (insn)); - while (delay_entry && delay_cost == 0) + if (pass == 0) + continue; + cost = min_cost_group; + reason = "not in sched group"; + } + else if (modulo_epilogue_p + && INSN_EXACT_TICK (insn) == INVALID_TICK) + { + cost = max_insn_queue_index; + reason = "not an epilogue insn"; + } + else if (shadows_only_p && !SHADOW_P (insn)) + { + cost = 1; + reason = "not a shadow"; + } + else if (recog_memoized (insn) < 0) + { + if (!first_cycle_insn_p + && (GET_CODE (PATTERN (insn)) == ASM_INPUT + || asm_noperands (PATTERN (insn)) >= 0)) + cost = 1; + reason = "asm"; + } + else if (sched_pressure_p) + cost = 0; + else + { + int delay_cost = 0; + + if (delay_htab) { - delay_cost = estimate_shadow_tick (delay_entry); - if (delay_cost > max_insn_queue_index) - delay_cost = max_insn_queue_index; - delay_entry = delay_entry->next_same_i1; + struct delay_pair *delay_entry; + delay_entry + = (struct delay_pair *)htab_find_with_hash (delay_htab, insn, + htab_hash_pointer (insn)); + while (delay_entry && delay_cost == 0) + { + delay_cost = estimate_shadow_tick (delay_entry); + if (delay_cost > max_insn_queue_index) + delay_cost = max_insn_queue_index; + delay_entry = delay_entry->next_same_i1; + } } - } - memcpy (temp_state, curr_state, dfa_state_size); - cost = state_transition (temp_state, insn); - if (cost < 0) - cost = 0; - else if (cost == 0) - cost = 1; - if (cost < delay_cost) + memcpy (temp_state, curr_state, dfa_state_size); + cost = state_transition (temp_state, insn); + if (cost < 0) + cost = 0; + else if (cost == 0) + cost = 1; + if (cost < delay_cost) + { + cost = delay_cost; + reason = "shadow tick"; + } + } + if (cost >= 1) { - cost = delay_cost; - reason = "shadow tick"; + if (SCHED_GROUP_P (insn) && cost > min_cost_group) + min_cost_group = cost; + ready_remove (&ready, i); + queue_insn (insn, cost, reason); + if (i + 1 < n) + break; } } - if (cost >= 1) - { - ready_remove (&ready, i); - queue_insn (insn, cost, reason); - goto restart; - } + if (i == n) + pass++; } } |