This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [3/4] SMS: Record moves in the partial schedule


On Wed, Sep 28, 2011 at 4:53 PM, Richard Sandiford
<richard.sandiford@linaro.org> wrote:
> Ayal Zaks <ayal.zaks@gmail.com> writes:
>>>> Only request is to document that the register moves are
>>>> placed/assigned-id'sÂin a specific order.
>>>
>>>I suppose this is the downside of splitting the patches up, sorry,
>>>but the ids are only ordered for the throw-away loop:
>>>
>>>ÂFOR_EACH_VEC_ELT_REVERSE (ps_reg_move_info, ps->reg_moves, i, move)
>>>Â Âadd_insn_before (move->insn, ps_first_note (ps, move->def), NULL);
>>>
>>>and for the prologue/epilogue code. ÂBoth are replaced in patch 4
>>>with code that doesn't rely on the ordering of ids.
>> Ok then, very well. I was mostly referring to the following in
>> prologue/epiloque code, which merely relies on assigningÂall regmoves
>> of a node consecutive id's:
>
> FWIW, the 4/4 that I just posted did finally get rid of the first_reg_move
> & nreg_moves fields.
>
> Here's a slightly updated patch in line with your 4/4 comments.
> The move->def is now always the id of the predecessor, rather than
> the id of the original ddg node producer. ÂI've adapted the throw-away
> loop accordingly, but there are no other changes.
>

This is ok.

Just to make sure I follow, the changes were (for this patch):

1. setting up a different move->def for each move

> +         move->def = i_reg_move > 0 ? first_move + i_reg_move - 1 : i;

instead of the same original def for all

> +      move->def = i;

2. inserting each move right before its own def, bottom-up:

> +  FOR_EACH_VEC_ELT (ps_reg_move_info, ps->reg_moves, i, move)
> +    add_insn_before (move->insn, ps_first_note (ps, move->def), NULL);

instead of inserting each move right before the original def, top-down:

>>> FOR_EACH_VEC_ELT_REVERSE (ps_reg_move_info, ps->reg_moves, i, move)
>>>   add_insn_before (move->insn, ps_first_note (ps, move->def), NULL);

Thanks,
Ayal.


> Tested on powerpc64-linux-gnu and with ARM benchmarks.
>
> Richard
>
> gcc/
> Â Â Â Â* modulo-sched.c (ps_insn): Adjust comment.
> Â Â Â Â(ps_reg_move_info): New structure.
> Â Â Â Â(partial_schedule): Add reg_moves field.
> Â Â Â Â(SCHED_PARAMS): Use node_sched_param_vec instead of node_sched_params.
> Â Â Â Â(node_sched_params): Turn first_reg_move into an identifier.
> Â Â Â Â(ps_reg_move): New function.
> Â Â Â Â(ps_rtl_insn): Cope with register moves.
> Â Â Â Â(ps_first_note): Adjust comment and assert that the instruction
> Â Â Â Âisn't a register move.
> Â Â Â Â(node_sched_params): Replace with...
> Â Â Â Â(node_sched_param_vec): ...this vector.
> Â Â Â Â(set_node_sched_params): Adjust accordingly.
> Â Â Â Â(print_node_sched_params): Take a partial schedule instead of a ddg.
> Â Â Â ÂUse ps_rtl_insn and ps_reg_move.
> Â Â Â Â(generate_reg_moves): Rename to...
> Â Â Â Â(schedule_reg_moves): ...this. ÂRemove rescan parameter. ÂRecord each
> Â Â Â Âmove in the partial schedule, but don't emit it here. ÂDon't perform
> Â Â Â Âregister substitutions here either.
> Â Â Â Â(apply_reg_moves): New function.
> Â Â Â Â(duplicate_insns_of_cycles): Use register indices directly,
> Â Â Â Ârather than finding instructions using PREV_INSN. ÂUse ps_reg_move.
> Â Â Â Â(sms_schedule): Call schedule_reg_moves before committing to
> Â Â Â Âa partial schedule. Â Try the next ii if the schedule fails.
> Â Â Â ÂUse apply_reg_moves instead of generate_reg_moves. ÂAdjust
> Â Â Â Âcall to print_node_sched_params. ÂFree node_sched_param_vec
> Â Â Â Âinstead of node_sched_params.
> Â Â Â Â(create_partial_schedule): Initialize reg_moves.
> Â Â Â Â(free_partial_schedule): Free reg_moves.
>
> Index: gcc/modulo-sched.c
> ===================================================================
> --- gcc/modulo-sched.c Â2011-09-28 09:03:10.334301485 +0100
> +++ gcc/modulo-sched.c Â2011-09-28 11:24:26.530300781 +0100
> @@ -124,7 +124,9 @@ #define PS_STAGE_COUNT(ps) (((partial_sc
> Â/* A single instruction in the partial schedule. Â*/
> Âstruct ps_insn
> Â{
> - Â/* The number of the ddg node whose instruction is being scheduled. Â*/
> + Â/* Identifies the instruction to be scheduled. ÂValues smaller than
> + Â Â the ddg's num_nodes refer directly to ddg nodes. ÂA value of
> + Â Â X - num_nodes refers to register move X. Â*/
> Â int id;
>
> Â /* The (absolute) cycle in which the PS instruction is scheduled.
> @@ -137,6 +139,30 @@ struct ps_insn
>
> Â};
>
> +/* Information about a register move that has been added to a partial
> + Â schedule. Â*/
> +struct ps_reg_move_info
> +{
> + Â/* The source of the move is defined by the ps_insn with id DEF.
> + Â Â The destination is used by the ps_insns with the ids in USES. Â*/
> + Âint def;
> + Âsbitmap uses;
> +
> + Â/* The original form of USES' instructions used OLD_REG, but they
> + Â Â should now use NEW_REG. Â*/
> + Ârtx old_reg;
> + Ârtx new_reg;
> +
> + Â/* An instruction that sets NEW_REG to the correct value. ÂThe first
> + Â Â move associated with DEF will have an rhs of OLD_REG; later moves
> + Â Â use the result of the previous move. Â*/
> + Ârtx insn;
> +};
> +
> +typedef struct ps_reg_move_info ps_reg_move_info;
> +DEF_VEC_O (ps_reg_move_info);
> +DEF_VEC_ALLOC_O (ps_reg_move_info, heap);
> +
> Â/* Holds the partial schedule as an array of II rows. ÂEach entry of the
> Â Âarray points to a linked list of PS_INSNs, which represents the
> Â Âinstructions that are scheduled for that row. Â*/
> @@ -148,6 +174,10 @@ struct partial_schedule
> Â /* rows[i] points to linked list of insns scheduled in row i (0<=i<ii). Â*/
> Â ps_insn_ptr *rows;
>
> + Â/* All the moves added for this partial schedule. ÂIndex X has
> + Â Â a ps_insn id of X + g->num_nodes. Â*/
> + ÂVEC (ps_reg_move_info, heap) *reg_moves;
> +
> Â /* Ârows_length[i] holds the number of instructions in the row.
> Â Â Â It is used only (as an optimization) to back off quickly from
> Â Â Â trying to schedule a node in a full row; that is, to avoid running
> @@ -201,7 +231,7 @@ static void remove_node_from_ps (partial
>
> Â#define NODE_ASAP(node) ((node)->aux.count)
>
> -#define SCHED_PARAMS(x) (&node_sched_params[x])
> +#define SCHED_PARAMS(x) VEC_index (node_sched_params, node_sched_param_vec, x)
> Â#define SCHED_TIME(x) (SCHED_PARAMS (x)->time)
> Â#define SCHED_FIRST_REG_MOVE(x) (SCHED_PARAMS (x)->first_reg_move)
> Â#define SCHED_NREG_MOVES(x) (SCHED_PARAMS (x)->nreg_moves)
> @@ -214,14 +244,13 @@ typedef struct node_sched_params
> Â{
> Â int time; Â Â/* The absolute scheduling cycle. Â*/
>
> - Â/* The following field (first_reg_move) is a pointer to the first
> + Â/* The following field (first_reg_move) is the ps_insn id of the first
> Â Â Âregister-move instruction added to handle the modulo-variable-expansion
> Â Â Âof the register defined by this node. ÂThis register-move copies the
> Â Â Âoriginal register defined by the node. Â*/
> - Ârtx first_reg_move;
> + Âint first_reg_move;
>
> - Â/* The number of register-move instructions added, immediately preceding
> - Â Â first_reg_move. Â*/
> + Â/* The number of register-move instructions added. Â*/
> Â int nreg_moves;
>
> Â int row; Â Â/* Holds time % ii. Â*/
> @@ -232,6 +261,9 @@ typedef struct node_sched_params
> Â int column;
> Â} *node_sched_params_ptr;
>
> +typedef struct node_sched_params node_sched_params;
> +DEF_VEC_O (node_sched_params);
> +DEF_VEC_ALLOC_O (node_sched_params, heap);
>
> Â/* The following three functions are copied from the current scheduler
> Â Âcode in order to use sched_analyze() for computing the dependencies.
> @@ -280,20 +312,35 @@ static struct haifa_sched_info sms_sched
> Â 0
> Â};
>
> +/* Partial schedule instruction ID in PS is a register move. ÂReturn
> + Â information about it. Â*/
> +static struct ps_reg_move_info *
> +ps_reg_move (partial_schedule_ptr ps, int id)
> +{
> + Âgcc_checking_assert (id >= ps->g->num_nodes);
> + Âreturn VEC_index (ps_reg_move_info, ps->reg_moves, id - ps->g->num_nodes);
> +}
> +
> Â/* Return the rtl instruction that is being scheduled by partial schedule
> Â Âinstruction ID, which belongs to schedule PS. Â*/
> Âstatic rtx
> Âps_rtl_insn (partial_schedule_ptr ps, int id)
> Â{
> - Âreturn ps->g->nodes[id].insn;
> + Âif (id < ps->g->num_nodes)
> + Â Âreturn ps->g->nodes[id].insn;
> + Âelse
> + Â Âreturn ps_reg_move (ps, id)->insn;
> Â}
>
> -/* Return the first instruction in the original (unscheduled) loop that
> - Â was associated with ps_rtl_insn (PS, ID). ÂIf the instruction had
> - Â some notes before it, this is the first of those notes. Â*/
> +/* Partial schedule instruction ID, which belongs to PS, occured in
> + Â the original (unscheduled) loop. ÂReturn the first instruction
> + Â in the loop that was associated with ps_rtl_insn (PS, ID).
> + Â If the instruction had some notes before it, this is the first
> + Â of those notes. Â*/
> Âstatic rtx
> Âps_first_note (partial_schedule_ptr ps, int id)
> Â{
> + Âgcc_assert (id < ps->g->num_nodes);
> Â return ps->g->nodes[id].first_note;
> Â}
>
> @@ -397,18 +444,20 @@ res_MII (ddg_ptr g)
> Â}
>
>
> -/* Points to the array that contains the sched data for each node. Â*/
> -static node_sched_params_ptr node_sched_params;
> +/* A vector that contains the sched data for each ps_insn. Â*/
> +static VEC (node_sched_params, heap) *node_sched_param_vec;
>
> Â/* Allocate sched_params for each node and initialize it. Â*/
> Âstatic void
> Âset_node_sched_params (ddg_ptr g)
> Â{
> - Ânode_sched_params = XCNEWVEC (struct node_sched_params, g->num_nodes);
> + ÂVEC_truncate (node_sched_params, node_sched_param_vec, 0);
> + ÂVEC_safe_grow_cleared (node_sched_params, heap,
> + Â Â Â Â Â Â Â Â Â Â Â Ânode_sched_param_vec, g->num_nodes);
> Â}
>
> Âstatic void
> -print_node_sched_params (FILE *file, int num_nodes, ddg_ptr g)
> +print_node_sched_params (FILE *file, int num_nodes, partial_schedule_ptr ps)
> Â{
> Â int i;
>
> @@ -417,19 +466,19 @@ print_node_sched_params (FILE *file, int
> Â for (i = 0; i < num_nodes; i++)
> Â Â {
> Â Â Â node_sched_params_ptr nsp = SCHED_PARAMS (i);
> - Â Â Ârtx reg_move = nsp->first_reg_move;
> Â Â Â int j;
>
> Â Â Â fprintf (file, "Node = %d; INSN = %d\n", i,
> - Â Â Â Â Â Â Â(INSN_UID (g->nodes[i].insn)));
> - Â Â Âfprintf (file, " asap = %d:\n", NODE_ASAP (&g->nodes[i]));
> + Â Â Â Â Â Â ÂINSN_UID (ps_rtl_insn (ps, i)));
> + Â Â Âfprintf (file, " asap = %d:\n", NODE_ASAP (&ps->g->nodes[i]));
> Â Â Â fprintf (file, " time = %d:\n", nsp->time);
> Â Â Â fprintf (file, " nreg_moves = %d:\n", nsp->nreg_moves);
> Â Â Â for (j = 0; j < nsp->nreg_moves; j++)
> Â Â Â Â{
> + Â Â Â Â ps_reg_move_info *move = ps_reg_move (ps, nsp->first_reg_move + j);
> +
> Â Â Â Â Âfprintf (file, " reg_move = ");
> - Â Â Â Â print_rtl_single (file, reg_move);
> - Â Â Â Â reg_move = PREV_INSN (reg_move);
> + Â Â Â Â print_rtl_single (file, move->insn);
> Â Â Â Â}
> Â Â }
> Â}
> @@ -445,8 +494,8 @@ print_node_sched_params (FILE *file, int
> Â Ânreg_moves = ----------------------------------- + 1 - { Â dependence.
>               ii             Â{ 1 if not.
> Â*/
> -static void
> -generate_reg_moves (partial_schedule_ptr ps, bool rescan)
> +static bool
> +schedule_reg_moves (partial_schedule_ptr ps)
> Â{
> Â ddg_ptr g = ps->g;
> Â int ii = ps->ii;
> @@ -457,9 +506,8 @@ generate_reg_moves (partial_schedule_ptr
> Â Â Â ddg_node_ptr u = &g->nodes[i];
> Â Â Â ddg_edge_ptr e;
> Â Â Â int nreg_moves = 0, i_reg_move;
> - Â Â Âsbitmap *uses_of_defs;
> - Â Â Ârtx last_reg_move;
> Â Â Â rtx prev_reg, old_reg;
> + Â Â Âint first_move;
>
> Â Â Â /* Compute the number of reg_moves needed for u, by looking at life
> Â Â Â Â ranges started at u (excluding self-loops). Â*/
> @@ -485,12 +533,35 @@ generate_reg_moves (partial_schedule_ptr
> Â Â Â if (nreg_moves == 0)
> Â Â Â Âcontinue;
>
> + Â Â Â/* Create NREG_MOVES register moves. Â*/
> + Â Â Âfirst_move = VEC_length (ps_reg_move_info, ps->reg_moves);
> + Â Â ÂVEC_safe_grow_cleared (ps_reg_move_info, heap, ps->reg_moves,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Âfirst_move + nreg_moves);
> +
> + Â Â Â/* Record the moves associated with this node. Â*/
> + Â Â Âfirst_move += ps->g->num_nodes;
> + Â Â ÂSCHED_FIRST_REG_MOVE (i) = first_move;
> + Â Â ÂSCHED_NREG_MOVES (i) = nreg_moves;
> +
> + Â Â Â/* Generate each move. Â*/
> + Â Â Âold_reg = prev_reg = SET_DEST (single_set (u->insn));
> + Â Â Âfor (i_reg_move = 0; i_reg_move < nreg_moves; i_reg_move++)
> + Â Â Â {
> + Â Â Â Â ps_reg_move_info *move = ps_reg_move (ps, first_move + i_reg_move);
> +
> + Â Â Â Â move->def = i_reg_move > 0 ? first_move + i_reg_move - 1 : i;
> + Â Â Â Â move->uses = sbitmap_alloc (g->num_nodes);
> + Â Â Â Â move->old_reg = old_reg;
> + Â Â Â Â move->new_reg = gen_reg_rtx (GET_MODE (prev_reg));
> + Â Â Â Â move->insn = gen_move_insn (move->new_reg, copy_rtx (prev_reg));
> + Â Â Â Â sbitmap_zero (move->uses);
> +
> + Â Â Â Â prev_reg = move->new_reg;
> + Â Â Â }
> +
> Â Â Â /* Every use of the register defined by node may require a different
> Â Â Â Â copy of this register, depending on the time the use is scheduled.
> - Â Â Â ÂSet a bitmap vector, telling which nodes use each copy of this
> - Â Â Â Âregister. Â*/
> - Â Â Âuses_of_defs = sbitmap_vector_alloc (nreg_moves, g->num_nodes);
> - Â Â Âsbitmap_vector_zero (uses_of_defs, nreg_moves);
> + Â Â Â ÂRecord which uses require which move results. Â*/
> Â Â Â for (e = u->out; e; e = e->next_out)
> Â Â Â Âif (e->type == TRUE_DEP && e->dest != e->src)
> Â Â Â Â Â{
> @@ -506,40 +577,39 @@ generate_reg_moves (partial_schedule_ptr
> Â Â Â Â Â Â Âdest_copy--;
>
> Â Â Â Â Â Âif (dest_copy)
> - Â Â Â Â Â Â SET_BIT (uses_of_defs[dest_copy - 1], e->dest->cuid);
> - Â Â Â Â }
> -
> - Â Â Â/* Now generate the reg_moves, attaching relevant uses to them. Â*/
> - Â Â ÂSCHED_NREG_MOVES (i) = nreg_moves;
> - Â Â Âold_reg = prev_reg = copy_rtx (SET_DEST (single_set (u->insn)));
> - Â Â Â/* Insert the reg-moves right before the notes which precede
> - Â Â Â Â the insn they relates to. Â*/
> - Â Â Âlast_reg_move = u->first_note;
> -
> - Â Â Âfor (i_reg_move = 0; i_reg_move < nreg_moves; i_reg_move++)
> - Â Â Â {
> - Â Â Â Â unsigned int i_use = 0;
> - Â Â Â Â rtx new_reg = gen_reg_rtx (GET_MODE (prev_reg));
> - Â Â Â Â rtx reg_move = gen_move_insn (new_reg, prev_reg);
> - Â Â Â Â sbitmap_iterator sbi;
> + Â Â Â Â Â Â {
> + Â Â Â Â Â Â Â ps_reg_move_info *move;
>
> - Â Â Â Â add_insn_before (reg_move, last_reg_move, NULL);
> - Â Â Â Â last_reg_move = reg_move;
> + Â Â Â Â Â Â Â move = ps_reg_move (ps, first_move + dest_copy - 1);
> + Â Â Â Â Â Â Â SET_BIT (move->uses, e->dest->cuid);
> + Â Â Â Â Â Â }
> + Â Â Â Â }
> + Â Â}
> + Âreturn true;
> +}
>
> - Â Â Â Â if (!SCHED_FIRST_REG_MOVE (i))
> - Â Â Â Â Â SCHED_FIRST_REG_MOVE (i) = reg_move;
> +/* Emit the moves associatied with PS. ÂApply the substitutions
> + Â associated with them. Â*/
> +static void
> +apply_reg_moves (partial_schedule_ptr ps)
> +{
> + Âps_reg_move_info *move;
> + Âint i;
>
> - Â Â Â Â EXECUTE_IF_SET_IN_SBITMAP (uses_of_defs[i_reg_move], 0, i_use, sbi)
> - Â Â Â Â Â {
> - Â Â Â Â Â Â replace_rtx (g->nodes[i_use].insn, old_reg, new_reg);
> - Â Â Â Â Â Â if (rescan)
> - Â Â Â Â Â Â Â df_insn_rescan (g->nodes[i_use].insn);
> - Â Â Â Â Â }
> + ÂFOR_EACH_VEC_ELT (ps_reg_move_info, ps->reg_moves, i, move)
> + Â Â{
> + Â Â Âunsigned int i_use;
> + Â Â Âsbitmap_iterator sbi;
>
> - Â Â Â Â prev_reg = new_reg;
> + Â Â ÂEXECUTE_IF_SET_IN_SBITMAP (move->uses, 0, i_use, sbi)
> + Â Â Â {
> + Â Â Â Â replace_rtx (ps->g->nodes[i_use].insn, move->old_reg, move->new_reg);
> + Â Â Â Â df_insn_rescan (ps->g->nodes[i_use].insn);
> Â Â Â Â}
> - Â Â Âsbitmap_vector_free (uses_of_defs);
> Â Â }
> +
> + ÂFOR_EACH_VEC_ELT (ps_reg_move_info, ps->reg_moves, i, move)
> + Â Âadd_insn_before (move->insn, ps_first_note (ps, move->def), NULL);
> Â}
>
> Â/* Update the sched_params (time, row and stage) for node U using the II,
> @@ -855,8 +925,7 @@ duplicate_insns_of_cycles (partial_sched
> Â Â for (ps_ij = ps->rows[row]; ps_ij; ps_ij = ps_ij->next_in_row)
> Â Â Â {
> Â Â Â Âint u = ps_ij->id;
> - Â Â Â int j, i_reg_moves;
> - Â Â Â rtx reg_move = NULL_RTX;
> + Â Â Â int j, i_reg_moves, i_reg_move;
> Â Â Â Ârtx u_insn;
>
> Â Â Â Â /* Do not duplicate any insn which refers to count_reg as it
> @@ -880,12 +949,7 @@ duplicate_insns_of_cycles (partial_sched
> Â Â Â Â Â Âi_reg_moves = MIN (i_reg_moves, SCHED_NREG_MOVES (u));
>
> Â Â Â Â Â Â/* The reg_moves start from the *first* reg_move backwards. Â*/
> - Â Â Â Â Â if (i_reg_moves)
> - Â Â Â Â Â Â {
> - Â Â Â Â Â Â Â reg_move = SCHED_FIRST_REG_MOVE (u);
> - Â Â Â Â Â Â Â for (j = 1; j < i_reg_moves; j++)
> - Â Â Â Â Â Â Â Â reg_move = PREV_INSN (reg_move);
> - Â Â Â Â Â Â }
> + Â Â Â Â Â i_reg_move = SCHED_FIRST_REG_MOVE (u) + (i_reg_moves - 1);
> Â Â Â Â Â}
> Â Â Â Âelse /* It's for the epilog. Â*/
> Â Â Â Â Â{
> @@ -899,16 +963,15 @@ duplicate_insns_of_cycles (partial_sched
> Â Â Â Â Â Âi_reg_moves = MIN (i_reg_moves, SCHED_NREG_MOVES (u));
>
> Â Â Â Â Â Â/* The reg_moves start from the *last* reg_move forwards. Â*/
> - Â Â Â Â Â if (i_reg_moves)
> - Â Â Â Â Â Â {
> - Â Â Â Â Â Â Â reg_move = SCHED_FIRST_REG_MOVE (u);
> - Â Â Â Â Â Â Â for (j = 1; j < SCHED_NREG_MOVES (u); j++)
> - Â Â Â Â Â Â Â Â reg_move = PREV_INSN (reg_move);
> - Â Â Â Â Â Â }
> + Â Â Â Â Â i_reg_move = SCHED_FIRST_REG_MOVE (u) + (SCHED_NREG_MOVES (u) - 1);
> Â Â Â Â Â}
>
> - Â Â Â for (j = 0; j < i_reg_moves; j++, reg_move = NEXT_INSN (reg_move))
> - Â Â Â Â emit_insn (copy_rtx (PATTERN (reg_move)));
> + Â Â Â for (j = 0; j < i_reg_moves; j++)
> + Â Â Â Â {
> + Â Â Â Â Â ps_reg_move_info *move = ps_reg_move (ps, i_reg_move - j);
> +
> + Â Â Â Â Â emit_insn (copy_rtx (PATTERN (move->insn)));
> + Â Â Â Â }
> Â Â Â Âif (SCHED_STAGE (u) >= from_stage
> Â Â Â Â Â Â&& SCHED_STAGE (u) <= to_stage)
> Â Â Â Â Âduplicate_insn_chain (ps_first_note (ps, u), u_insn);
> @@ -1299,9 +1362,9 @@ sms_schedule (void)
> Â Â Â rtx head, tail;
> Â Â Â rtx count_reg, count_init;
> Â Â Â int mii, rec_mii;
> - Â Â Âunsigned stage_count = 0;
> + Â Â Âunsigned stage_count;
> Â Â Â HOST_WIDEST_INT loop_count = 0;
> - Â Â Âbool opt_sc_p = false;
> + Â Â Âbool opt_sc_p;
>
> Â Â Â if (! (g = g_arr[loop->num]))
> Â Â Â Â continue;
> @@ -1378,54 +1441,60 @@ sms_schedule (void)
> Â Â Â Âfprintf (dump_file, "SMS iis %d %d %d (rec_mii, mii, maxii)\n",
> Â Â Â Â Â Â Â Â rec_mii, mii, maxii);
>
> - Â Â Âset_node_sched_params (g);
> -
> - Â Â Âps = sms_schedule_by_order (g, mii, maxii, node_order);
> -
> - Â Â Âif (ps)
> + Â Â Âfor (;;)
> Â Â Â Â{
> - Â Â Â Â /* Try to achieve optimized SC by normalizing the partial
> - Â Â Â Â Â Âschedule (having the cycles start from cycle zero).
> - Â Â Â Â Â ÂThe branch location must be placed in row ii-1 in the
> - Â Â Â Â Â Âfinal scheduling. ÂIf failed, shift all instructions to
> - Â Â Â Â Â Âposition the branch in row ii-1. Â*/
> - Â Â Â Â opt_sc_p = optimize_sc (ps, g);
> - Â Â Â Â if (opt_sc_p)
> - Â Â Â Â Â stage_count = calculate_stage_count (ps, 0);
> - Â Â Â Â else
> + Â Â Â Â set_node_sched_params (g);
> +
> + Â Â Â Â stage_count = 0;
> + Â Â Â Â opt_sc_p = false;
> + Â Â Â Â ps = sms_schedule_by_order (g, mii, maxii, node_order);
> +
> + Â Â Â Â if (ps)
> Â Â Â Â Â Â{
> - Â Â Â Â Â Â /* Bring the branch to cycle ii-1. Â*/
> - Â Â Â Â Â Â int amount = SCHED_TIME (g->closing_branch->cuid) - (ps->ii - 1);
> -
> - Â Â Â Â Â Â if (dump_file)
> - Â Â Â Â Â Â Â fprintf (dump_file, "SMS schedule branch at cycle ii-1\n");
> -
> - Â Â Â Â Â Â stage_count = calculate_stage_count (ps, amount);
> + Â Â Â Â Â Â /* Try to achieve optimized SC by normalizing the partial
> + Â Â Â Â Â Â Â Âschedule (having the cycles start from cycle zero).
> + Â Â Â Â Â Â Â ÂThe branch location must be placed in row ii-1 in the
> + Â Â Â Â Â Â Â Âfinal scheduling. Â Â ÂIf failed, shift all instructions to
> + Â Â Â Â Â Â Â Âposition the branch in row ii-1. Â*/
> + Â Â Â Â Â Â opt_sc_p = optimize_sc (ps, g);
> + Â Â Â Â Â Â if (opt_sc_p)
> + Â Â Â Â Â Â Â stage_count = calculate_stage_count (ps, 0);
> + Â Â Â Â Â Â else
> + Â Â Â Â Â Â Â {
> + Â Â Â Â Â Â Â Â /* Bring the branch to cycle ii-1. Â*/
> + Â Â Â Â Â Â Â Â int amount = (SCHED_TIME (g->closing_branch->cuid)
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â - (ps->ii - 1));
> +
> + Â Â Â Â Â Â Â Â if (dump_file)
> + Â Â Â Â Â Â Â Â Â fprintf (dump_file, "SMS schedule branch at cycle ii-1\n");
> +
> + Â Â Â Â Â Â Â Â stage_count = calculate_stage_count (ps, amount);
> + Â Â Â Â Â Â Â }
> +
> + Â Â Â Â Â Â gcc_assert (stage_count >= 1);
> + Â Â Â Â Â Â PS_STAGE_COUNT (ps) = stage_count;
> Â Â Â Â Â Â}
> -
> - Â Â Â Â gcc_assert (stage_count >= 1);
> - Â Â Â Â PS_STAGE_COUNT (ps) = stage_count;
> - Â Â Â }
> -
> - Â Â Â/* The default value of PARAM_SMS_MIN_SC is 2 as stage count of
> - Â Â Â Â1 means that there is no interleaving between iterations thus
> - Â Â Â Âwe let the scheduling passes do the job in this case. Â*/
> - Â Â Âif (stage_count < (unsigned) PARAM_VALUE (PARAM_SMS_MIN_SC)
> - Â Â Â Â || (count_init && (loop_count <= stage_count))
> - Â Â Â Â || (flag_branch_probabilities && (trip_count <= stage_count)))
> - Â Â Â {
> - Â Â Â Â if (dump_file)
> +
> + Â Â Â Â /* The default value of PARAM_SMS_MIN_SC is 2 as stage count of
> + Â Â Â Â Â Â1 means that there is no interleaving between iterations thus
> + Â Â Â Â Â Âwe let the scheduling passes do the job in this case. Â*/
> + Â Â Â Â if (stage_count < (unsigned) PARAM_VALUE (PARAM_SMS_MIN_SC)
> + Â Â Â Â Â Â || (count_init && (loop_count <= stage_count))
> + Â Â Â Â Â Â || (flag_branch_probabilities && (trip_count <= stage_count)))
> Â Â Â Â Â Â{
> - Â Â Â Â Â Â fprintf (dump_file, "SMS failed... \n");
> - Â Â Â Â Â Â fprintf (dump_file, "SMS sched-failed (stage-count=%d, loop-count=", stage_count);
> - Â Â Â Â Â Â fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, loop_count);
> - Â Â Â Â Â Â fprintf (dump_file, ", trip-count=");
> - Â Â Â Â Â Â fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, trip_count);
> - Â Â Â Â Â Â fprintf (dump_file, ")\n");
> + Â Â Â Â Â Â if (dump_file)
> + Â Â Â Â Â Â Â {
> + Â Â Â Â Â Â Â Â fprintf (dump_file, "SMS failed... \n");
> + Â Â Â Â Â Â Â Â fprintf (dump_file, "SMS sched-failed (stage-count=%d,"
> + Â Â Â Â Â Â Â Â Â Â Â Â Â" loop-count=", stage_count);
> + Â Â Â Â Â Â Â Â fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, loop_count);
> + Â Â Â Â Â Â Â Â fprintf (dump_file, ", trip-count=");
> + Â Â Â Â Â Â Â Â fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, trip_count);
> + Â Â Â Â Â Â Â Â fprintf (dump_file, ")\n");
> + Â Â Â Â Â Â Â }
> + Â Â Â Â Â Â break;
> Â Â Â Â Â Â}
> - Â Â Â }
> - Â Â Âelse
> - Â Â Â {
> +
> Â Â Â Â Â if (!opt_sc_p)
> Â Â Â Â Â Â {
> Â Â Â Â Â Â Â/* Rotate the partial schedule to have the branch in row ii-1. Â*/
> @@ -1437,6 +1506,13 @@ sms_schedule (void)
>
> Â Â Â Â Âset_columns_for_ps (ps);
>
> + Â Â Â Â if (!schedule_reg_moves (ps))
> + Â Â Â Â Â {
> + Â Â Â Â Â Â mii = ps->ii + 1;
> + Â Â Â Â Â Â free_partial_schedule (ps);
> + Â Â Â Â Â Â continue;
> + Â Â Â Â Â }
> +
> Â Â Â Â Âcanon_loop (loop);
>
> Â Â Â Â Â if (dump_file)
> @@ -1475,15 +1551,16 @@ sms_schedule (void)
> Â Â Â Â Â/* The life-info is not valid any more. Â*/
> Â Â Â Â Âdf_set_bb_dirty (g->bb);
>
> - Â Â Â Â generate_reg_moves (ps, true);
> + Â Â Â Â apply_reg_moves (ps);
> Â Â Â Â Âif (dump_file)
> - Â Â Â Â Â print_node_sched_params (dump_file, g->num_nodes, g);
> + Â Â Â Â Â print_node_sched_params (dump_file, g->num_nodes, ps);
> Â Â Â Â Â/* Generate prolog and epilog. Â*/
> Â Â Â Â Â generate_prolog_epilog (ps, loop, count_reg, count_init);
> + Â Â Â Â break;
> Â Â Â Â}
>
> Â Â Â free_partial_schedule (ps);
> - Â Â Âfree (node_sched_params);
> + Â Â ÂVEC_free (node_sched_params, heap, node_sched_param_vec);
> Â Â Â free (node_order);
> Â Â Â free_ddg (g);
> Â Â }
> @@ -2570,6 +2647,7 @@ create_partial_schedule (int ii, ddg_ptr
> Â partial_schedule_ptr ps = XNEW (struct partial_schedule);
> Â ps->rows = (ps_insn_ptr *) xcalloc (ii, sizeof (ps_insn_ptr));
> Â ps->rows_length = (int *) xcalloc (ii, sizeof (int));
> + Âps->reg_moves = NULL;
> Â ps->ii = ii;
> Â ps->history = history;
> Â ps->min_cycle = INT_MAX;
> @@ -2604,8 +2682,16 @@ free_ps_insns (partial_schedule_ptr ps)
> Âstatic void
> Âfree_partial_schedule (partial_schedule_ptr ps)
> Â{
> + Âps_reg_move_info *move;
> + Âunsigned int i;
> +
> Â if (!ps)
> Â Â return;
> +
> + ÂFOR_EACH_VEC_ELT (ps_reg_move_info, ps->reg_moves, i, move)
> + Â Âsbitmap_free (move->uses);
> + ÂVEC_free (ps_reg_move_info, heap, ps->reg_moves);
> +
> Â free_ps_insns (ps);
> Â free (ps->rows);
> Â free (ps->rows_length);
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]