From bbd0cfb1ee5453effca14fbe2b11d946d2f597d1 Mon Sep 17 00:00:00 2001 From: steven Date: Sat, 8 Dec 2012 12:12:50 +0000 Subject: [PATCH] PR rtl-optimization/55158 * sched-rgn.c (bb_state_array, bb_state): Add some explaining comment, and initialize to NULL explicitly. (realloc_bb_state_array): New function. (free_bb_state_array): New function. (schedule_region): Call realloc_bb_state_array after schedule_block. (sched_rgn_init): Use realloc_bb_state_array to initialize bb_state. (sched_rgn_finish): Use free_bb_state_array to free it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@194322 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 11 +++++++ gcc/sched-rgn.c | 93 +++++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 79 insertions(+), 25 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cf7bb72..33f7597 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2012-12-08 Steven Bosscher + + PR rtl-optimization/55158 + * sched-rgn.c (bb_state_array, bb_state): Add some explaining + comment, and initialize to NULL explicitly. + (realloc_bb_state_array): New function. + (free_bb_state_array): New function. + (schedule_region): Call realloc_bb_state_array after schedule_block. + (sched_rgn_init): Use realloc_bb_state_array to initialize bb_state. + (sched_rgn_finish): Use free_bb_state_array to free it. + 2012-12-08 Eric Botcazou * tree-ssa-loop-im.c (for_each_index) : New case. diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c index 46edff8..7eed9ae 100644 --- a/gcc/sched-rgn.c +++ b/gcc/sched-rgn.c @@ -124,8 +124,12 @@ int current_blocks; static basic_block *bblst_table; static int bblst_size, bblst_last; -static char *bb_state_array; -static state_t *bb_state; +/* Arrays that hold the DFA state at the end of a basic block, to re-use + as the initial state at the start of successor blocks. The BB_STATE + array holds the actual DFA state, and BB_STATE_ARRAY[I] is a pointer + into BB_STATE for basic block I. FIXME: This should be a vec. */ +static char *bb_state_array = NULL; +static state_t *bb_state = NULL; /* Target info declarations. @@ -2903,6 +2907,61 @@ compute_priorities (void) current_sched_info->sched_max_insns_priority++; } +/* (Re-)initialize the arrays of DFA states at the end of each basic block. + + SAVED_LAST_BASIC_BLOCK is the previous length of the arrays. It must be + zero for the first call to this function, to allocate the arrays for the + first time. + + This function is called once during initialization of the scheduler, and + called again to resize the arrays if new basic blocks have been created, + for example for speculation recovery code. */ + +static void +realloc_bb_state_array (int saved_last_basic_block) +{ + char *old_bb_state_array = bb_state_array; + size_t lbb = (size_t) last_basic_block; + size_t slbb = (size_t) saved_last_basic_block; + + /* Nothing to do if nothing changed since the last time this was called. */ + if (saved_last_basic_block == last_basic_block) + return; + + /* The selective scheduler doesn't use the state arrays. */ + if (sel_sched_p ()) + { + gcc_assert (bb_state_array == NULL && bb_state == NULL); + return; + } + + gcc_checking_assert (saved_last_basic_block == 0 + || (bb_state_array != NULL && bb_state != NULL)); + + bb_state_array = XRESIZEVEC (char, bb_state_array, lbb * dfa_state_size); + bb_state = XRESIZEVEC (state_t, bb_state, lbb); + + /* If BB_STATE_ARRAY has moved, fixup all the state pointers array. + Otherwise only fixup the newly allocated ones. For the state + array itself, only initialize the new entries. */ + bool bb_state_array_moved = (bb_state_array != old_bb_state_array); + for (size_t i = bb_state_array_moved ? 0 : slbb; i < lbb; i++) + bb_state[i] = (state_t) (bb_state_array + i * dfa_state_size); + for (size_t i = slbb; i < lbb; i++) + state_reset (bb_state[i]); +} + +/* Free the arrays of DFA states at the end of each basic block. */ + +static void +free_bb_state_array (void) +{ + free (bb_state_array); + free (bb_state); + bb_state_array = NULL; + bb_state = NULL; +} + /* Schedule a region. A region is either an inner loop, a loop-free subroutine, or a single basic block. Each bb in the region is scheduled after its flow predecessors. */ @@ -2986,10 +3045,12 @@ schedule_region (int rgn) if (dbg_cnt (sched_block)) { edge f; + int saved_last_basic_block = last_basic_block; - schedule_block (&curr_bb, bb_state[first_bb->index]); - gcc_assert (EBB_FIRST_BB (bb) == first_bb); - sched_rgn_n_insns += sched_n_insns; + schedule_block (&curr_bb, bb_state[first_bb->index]); + gcc_assert (EBB_FIRST_BB (bb) == first_bb); + sched_rgn_n_insns += sched_n_insns; + realloc_bb_state_array (saved_last_basic_block); f = find_fallthru_edge (last_bb->succs); if (f && f->probability * 100 / REG_BR_PROB_BASE >= PARAM_VALUE (PARAM_SCHED_STATE_EDGE_PROB_CUTOFF)) @@ -3032,8 +3093,6 @@ schedule_region (int rgn) void sched_rgn_init (bool single_blocks_p) { - int i; - min_spec_prob = ((PARAM_VALUE (PARAM_MIN_SPEC_PROB) * REG_BR_PROB_BASE) / 100); @@ -3045,22 +3104,7 @@ sched_rgn_init (bool single_blocks_p) CONTAINING_RGN (ENTRY_BLOCK) = -1; CONTAINING_RGN (EXIT_BLOCK) = -1; - if (!sel_sched_p ()) - { - bb_state_array = (char *) xmalloc (last_basic_block * dfa_state_size); - bb_state = XNEWVEC (state_t, last_basic_block); - for (i = 0; i < last_basic_block; i++) - { - bb_state[i] = (state_t) (bb_state_array + i * dfa_state_size); - - state_reset (bb_state[i]); - } - } - else - { - bb_state_array = NULL; - bb_state = NULL; - } + realloc_bb_state_array (0); /* Compute regions for scheduling. */ if (single_blocks_p @@ -3098,8 +3142,7 @@ sched_rgn_init (bool single_blocks_p) void sched_rgn_finish (void) { - free (bb_state_array); - free (bb_state); + free_bb_state_array (); /* Reposition the prologue and epilogue notes in case we moved the prologue/epilogue insns. */ -- 2.7.4