diff options
Diffstat (limited to 'toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99511.patch')
-rw-r--r-- | toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99511.patch | 582 |
1 files changed, 582 insertions, 0 deletions
diff --git a/toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99511.patch b/toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99511.patch new file mode 100644 index 0000000000..8d096c25d0 --- /dev/null +++ b/toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99511.patch @@ -0,0 +1,582 @@ +2011-05-13 Revital Eres <revital.eres@linaro.org> + + gcc/ + * loop-doloop.c (doloop_condition_get): Support new form of + doloop pattern and use prev_nondebug_insn instead of PREV_INSN. + * config/arm/thumb2.md (*thumb2_addsi3_compare0): Remove "*". + (doloop_end): New. + * config/arm/arm.md (*addsi3_compare0): Remove "*". + * params.def (sms-min-sc): New param flag. + * doc/invoke.texi (sms-min-sc): Document it. + * ddg.c (create_ddg_dep_from_intra_loop_link): If a true dep edge + enters the branch create an anti edge in the opposite direction + to prevent the creation of reg-moves. + (get_node_of_insn_uid, check_closing_branch_deps): Delete + functions. + (create_ddg): Restore previous definition and implementation. + * ddg.h (create_ddg): Restore previous definition. + * modulo-sched.c: Adjust comment to reflect the fact we are + scheduling closing branch. + (PS_STAGE_COUNT): Rename to CALC_STAGE_COUNT and redefine. + (stage_count): New field in struct partial_schedule. + (calculate_stage_count): New function. + (normalize_sched_times): Rename to reset_sched_times and handle + incrementing the sched time of the nodes by a constant value + passed as parameter. + (duplicate_insns_of_cycles): Skip closing branch. + (sms_schedule_by_order): Schedule closing branch. + (ps_insn_find_column): Handle closing branch. + (sms_schedule): Call reset_sched_times and adjust the code to + support scheduling of the closing branch. Use sms-min-sc. + Support new form of doloop pattern. + (ps_insert_empty_row): Update calls to normalize_sched_times + and rotate_partial_schedule functions. + (mark_doloop_insns): Remove. + +=== modified file 'gcc/ddg.c' +--- old/gcc/ddg.c 2011-03-24 07:45:38 +0000 ++++ new/gcc/ddg.c 2011-05-11 08:00:14 +0000 +@@ -60,8 +60,6 @@ + static ddg_edge_ptr create_ddg_edge (ddg_node_ptr, ddg_node_ptr, dep_type, + dep_data_type, int, int); + static void add_edge_to_ddg (ddg_ptr g, ddg_edge_ptr); +-static ddg_node_ptr get_node_of_insn_uid (ddg_ptr, int); +- + + /* Auxiliary variable for mem_read_insn_p/mem_write_insn_p. */ + static bool mem_ref_p; +@@ -199,6 +197,11 @@ + } + } + ++ /* If a true dep edge enters the branch create an anti edge in the ++ opposite direction to prevent the creation of reg-moves. */ ++ if ((DEP_TYPE (link) == REG_DEP_TRUE) && JUMP_P (dest_node->insn)) ++ create_ddg_dep_no_link (g, dest_node, src_node, ANTI_DEP, REG_DEP, 1); ++ + latency = dep_cost (link); + e = create_ddg_edge (src_node, dest_node, t, dt, latency, distance); + add_edge_to_ddg (g, e); +@@ -452,65 +455,12 @@ + sched_free_deps (head, tail, false); + } + +-/* Given DOLOOP_INSNS which holds the instructions that +- belong to the do-loop part; mark closing_branch_deps field in ddg G +- as TRUE if the do-loop part's instructions are dependent on the other +- loop instructions. Otherwise mark it as FALSE. */ +-static void +-check_closing_branch_deps (ddg_ptr g, sbitmap doloop_insns) +-{ +- sbitmap_iterator sbi; +- unsigned int u = 0; +- +- EXECUTE_IF_SET_IN_SBITMAP (doloop_insns, 0, u, sbi) +- { +- ddg_edge_ptr e; +- ddg_node_ptr u_node = get_node_of_insn_uid (g, u); +- +- gcc_assert (u_node); +- +- for (e = u_node->in; e != 0; e = e->next_in) +- { +- ddg_node_ptr v_node = e->src; +- +- if (((unsigned int) INSN_UID (v_node->insn) == u) +- || DEBUG_INSN_P (v_node->insn)) +- continue; +- +- /* Ignore dependencies between memory writes and the +- jump. */ +- if (JUMP_P (u_node->insn) +- && e->type == OUTPUT_DEP +- && mem_write_insn_p (v_node->insn)) +- continue; +- if (!TEST_BIT (doloop_insns, INSN_UID (v_node->insn))) +- { +- g->closing_branch_deps = 1; +- return; +- } +- } +- for (e = u_node->out; e != 0; e = e->next_out) +- { +- ddg_node_ptr v_node = e->dest; +- +- if (((unsigned int) INSN_UID (v_node->insn) == u) +- || DEBUG_INSN_P (v_node->insn)) +- continue; +- if (!TEST_BIT (doloop_insns, INSN_UID (v_node->insn))) +- { +- g->closing_branch_deps = 1; +- return; +- } +- } +- } +- g->closing_branch_deps = 0; +-} + + /* Given a basic block, create its DDG and return a pointer to a variable + of ddg type that represents it. + Initialize the ddg structure fields to the appropriate values. */ + ddg_ptr +-create_ddg (basic_block bb, sbitmap doloop_insns) ++create_ddg (basic_block bb, int closing_branch_deps) + { + ddg_ptr g; + rtx insn, first_note; +@@ -520,6 +470,7 @@ + g = (ddg_ptr) xcalloc (1, sizeof (struct ddg)); + + g->bb = bb; ++ g->closing_branch_deps = closing_branch_deps; + + /* Count the number of insns in the BB. */ + for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb)); +@@ -592,11 +543,6 @@ + /* Build the data dependency graph. */ + build_intra_loop_deps (g); + build_inter_loop_deps (g); +- +- /* Check whether the do-loop part is decoupled from the other loop +- instructions. */ +- check_closing_branch_deps (g, doloop_insns); +- + return g; + } + +@@ -890,18 +836,6 @@ + return NULL; + } + +-/* Given the uid of an instruction UID return the node that represents it. */ +-static ddg_node_ptr +-get_node_of_insn_uid (ddg_ptr g, int uid) +-{ +- int i; +- +- for (i = 0; i < g->num_nodes; i++) +- if (uid == INSN_UID (g->nodes[i].insn)) +- return &g->nodes[i]; +- return NULL; +-} +- + /* Given a set OPS of nodes in the DDG, find the set of their successors + which are not in OPS, and set their bits in SUCC. Bits corresponding to + OPS are cleared from SUCC. Leaves the other bits in SUCC unchanged. */ + +=== modified file 'gcc/ddg.h' +--- old/gcc/ddg.h 2011-03-24 07:45:38 +0000 ++++ new/gcc/ddg.h 2011-05-11 08:00:14 +0000 +@@ -167,7 +167,7 @@ + }; + + +-ddg_ptr create_ddg (basic_block, sbitmap); ++ddg_ptr create_ddg (basic_block, int closing_branch_deps); + void free_ddg (ddg_ptr); + + void print_ddg (FILE *, ddg_ptr); + +=== modified file 'gcc/doc/invoke.texi' +--- old/gcc/doc/invoke.texi 2011-04-17 23:04:58 +0000 ++++ new/gcc/doc/invoke.texi 2011-05-11 08:00:14 +0000 +@@ -8430,6 +8430,10 @@ + The maximum number of best instructions in the ready list that are considered + for renaming in the selective scheduler. The default value is 2. + ++@item sms-min-sc ++The minimum value of stage count that swing modulo scheduler will ++generate. The default value is 2. ++ + @item max-last-value-rtl + The maximum size measured as number of RTLs that can be recorded in an expression + in combiner for a pseudo register as last known value of that register. The default + +=== modified file 'gcc/modulo-sched.c' +--- old/gcc/modulo-sched.c 2011-03-24 07:45:38 +0000 ++++ new/gcc/modulo-sched.c 2011-05-11 08:00:14 +0000 +@@ -84,14 +84,13 @@ + II cycles (i.e. use register copies to prevent a def from overwriting + itself before reaching the use). + +- SMS works with countable loops (1) whose control part can be easily +- decoupled from the rest of the loop and (2) whose loop count can +- be easily adjusted. This is because we peel a constant number of +- iterations into a prologue and epilogue for which we want to avoid +- emitting the control part, and a kernel which is to iterate that +- constant number of iterations less than the original loop. So the +- control part should be a set of insns clearly identified and having +- its own iv, not otherwise used in the loop (at-least for now), which ++ SMS works with countable loops whose loop count can be easily ++ adjusted. This is because we peel a constant number of iterations ++ into a prologue and epilogue for which we want to avoid emitting ++ the control part, and a kernel which is to iterate that constant ++ number of iterations less than the original loop. So the control ++ part should be a set of insns clearly identified and having its ++ own iv, not otherwise used in the loop (at-least for now), which + initializes a register before the loop to the number of iterations. + Currently SMS relies on the do-loop pattern to recognize such loops, + where (1) the control part comprises of all insns defining and/or +@@ -116,7 +115,7 @@ + + /* The number of different iterations the nodes in ps span, assuming + the stage boundaries are placed efficiently. */ +-#define CALC_STAGE_COUNT(min_cycle,max_cycle,ii) ((max_cycle - min_cycle \ ++#define CALC_STAGE_COUNT(max_cycle,min_cycle,ii) ((max_cycle - min_cycle \ + + 1 + ii - 1) / ii) + /* The stage count of ps. */ + #define PS_STAGE_COUNT(ps) (((partial_schedule_ptr)(ps))->stage_count) +@@ -200,7 +199,6 @@ + static void duplicate_insns_of_cycles (partial_schedule_ptr, + int, int, int, rtx); + static int calculate_stage_count (partial_schedule_ptr ps); +- + #define SCHED_ASAP(x) (((node_sched_params_ptr)(x)->aux.info)->asap) + #define SCHED_TIME(x) (((node_sched_params_ptr)(x)->aux.info)->time) + #define SCHED_FIRST_REG_MOVE(x) \ +@@ -318,7 +316,7 @@ + : prev_nondebug_insn (tail)); + + for (insn = head; insn != first_insn_not_to_check; insn = NEXT_INSN (insn)) +- if (reg_mentioned_p (reg, insn) && NONDEBUG_INSN_P (insn)) ++ if (reg_mentioned_p (reg, insn) && !DEBUG_INSN_P (insn)) + { + if (dump_file) + { +@@ -337,24 +335,6 @@ + #endif + } + +-/* Mark in DOLOOP_INSNS the instructions that belong to the do-loop part. +- Use TAIL to recognize that part. */ +-static void +-mark_doloop_insns (sbitmap doloop_insns, rtx tail) +-{ +- rtx first_insn_not_to_check, insn; +- +- /* This is the first instruction which belongs the doloop part. */ +- first_insn_not_to_check = (GET_CODE (PATTERN (tail)) == PARALLEL ? tail +- : prev_nondebug_insn (tail)); +- +- sbitmap_zero (doloop_insns); +- for (insn = first_insn_not_to_check; insn != NEXT_INSN (tail); +- insn = NEXT_INSN (insn)) +- if (NONDEBUG_INSN_P (insn)) +- SET_BIT (doloop_insns, INSN_UID (insn)); +-} +- + /* Check if COUNT_REG is set to a constant in the PRE_HEADER block, so + that the number of iterations is a compile-time constant. If so, + return the rtx that sets COUNT_REG to a constant, and set COUNT to +@@ -607,44 +587,42 @@ + ddg_node_ptr u = crr_insn->node; + int normalized_time = SCHED_TIME (u) - amount; + int new_min_cycle = PS_MIN_CYCLE (ps) - amount; +- /* The first cycle in row zero after the rotation. */ +- int new_first_cycle_in_row_zero = +- new_min_cycle + ii - SMODULO (new_min_cycle, ii); ++ int sc_until_cycle_zero, stage; + +- if (dump_file) +- fprintf (dump_file, "crr_insn->node=%d, crr_insn->cycle=%d,\ +- min_cycle=%d\n", crr_insn->node->cuid, SCHED_TIME +- (u), ps->min_cycle); ++ if (dump_file) ++ { ++ /* Print the scheduling times after the rotation. */ ++ fprintf (dump_file, "crr_insn->node=%d (insn id %d), " ++ "crr_insn->cycle=%d, min_cycle=%d", crr_insn->node->cuid, ++ INSN_UID (crr_insn->node->insn), SCHED_TIME (u), ++ normalized_time); ++ if (JUMP_P (crr_insn->node->insn)) ++ fprintf (dump_file, " (branch)"); ++ fprintf (dump_file, "\n"); ++ } ++ + gcc_assert (SCHED_TIME (u) >= ps->min_cycle); + gcc_assert (SCHED_TIME (u) <= ps->max_cycle); + SCHED_TIME (u) = normalized_time; +- crr_insn->cycle = normalized_time; + SCHED_ROW (u) = SMODULO (normalized_time, ii); +- +- /* If min_cycle is in row zero after the rotation then +- the stage count can be calculated by dividing the cycle +- with ii. Otherwise, the calculation is done by dividing the +- SMSed kernel into two intervals: +- +- 1) min_cycle <= interval 0 < first_cycle_in_row_zero +- 2) first_cycle_in_row_zero <= interval 1 < max_cycle +- +- Cycles in interval 0 are in stage 0. The stage of cycles +- in interval 1 should be added by 1 to take interval 0 into +- account. */ +- if (SMODULO (new_min_cycle, ii) == 0) +- SCHED_STAGE (u) = normalized_time / ii; +- else +- { +- if (crr_insn->cycle < new_first_cycle_in_row_zero) +- SCHED_STAGE (u) = 0; +- else +- SCHED_STAGE (u) = +- ((SCHED_TIME (u) - new_first_cycle_in_row_zero) / ii) + 1; ++ ++ /* The calculation of stage count is done adding the number ++ of stages before cycle zero and after cycle zero. */ ++ sc_until_cycle_zero = CALC_STAGE_COUNT (-1, new_min_cycle, ii); ++ ++ if (SCHED_TIME (u) < 0) ++ { ++ stage = CALC_STAGE_COUNT (-1, SCHED_TIME (u), ii); ++ SCHED_STAGE (u) = sc_until_cycle_zero - stage; ++ } ++ else ++ { ++ stage = CALC_STAGE_COUNT (SCHED_TIME (u), 0, ii); ++ SCHED_STAGE (u) = sc_until_cycle_zero + stage - 1; + } + } + } +- ++ + /* Set SCHED_COLUMN of each node according to its position in PS. */ + static void + set_columns_for_ps (partial_schedule_ptr ps) +@@ -694,8 +672,8 @@ + + /* Do not duplicate any insn which refers to count_reg as it + belongs to the control part. +- If closing_branch_deps is true the closing branch is scheduled +- as well and thus should be ignored. ++ The closing branch is scheduled as well and thus should ++ be ignored. + TODO: This should be done by analyzing the control part of + the loop. */ + if (reg_mentioned_p (count_reg, u_node->insn) +@@ -945,8 +923,7 @@ + basic_block condition_bb = NULL; + edge latch_edge; + gcov_type trip_count = 0; +- sbitmap doloop_insns; +- ++ + loop_optimizer_init (LOOPS_HAVE_PREHEADERS + | LOOPS_HAVE_RECORDED_EXITS); + if (number_of_loops () <= 1) +@@ -971,7 +948,6 @@ + setup_sched_infos (); + haifa_sched_init (); + +- doloop_insns = sbitmap_alloc (get_max_uid () + 1); + /* Allocate memory to hold the DDG array one entry for each loop. + We use loop->num as index into this array. */ + g_arr = XCNEWVEC (ddg_ptr, number_of_loops ()); +@@ -1104,16 +1080,18 @@ + + continue; + } +- mark_doloop_insns (doloop_insns, tail); +- if (! (g = create_ddg (bb, doloop_insns))) ++ ++ /* Always schedule the closing branch with the rest of the ++ instructions. The branch is rotated to be in row ii-1 at the ++ end of the scheduling procedure to make sure it's the last ++ instruction in the iteration. */ ++ if (! (g = create_ddg (bb, 1))) + { + if (dump_file) + fprintf (dump_file, "SMS create_ddg failed\n"); + continue; + } +- if (dump_file) +- fprintf (dump_file, "SMS closing_branch_deps: %d\n", +- g->closing_branch_deps); ++ + g_arr[loop->num] = g; + if (dump_file) + fprintf (dump_file, "...OK\n"); +@@ -1215,16 +1193,17 @@ + + ps = sms_schedule_by_order (g, mii, maxii, node_order); + +- if (ps) +- { +- stage_count = calculate_stage_count (ps); +- gcc_assert(stage_count >= 1); +- PS_STAGE_COUNT(ps) = stage_count; +- } +- +- /* Stage count of 1 means that there is no interleaving between +- iterations, let the scheduling passes do the job. */ +- if (stage_count <= 1 ++ if (ps) ++ { ++ stage_count = calculate_stage_count (ps); ++ 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))) + { +@@ -1242,21 +1221,12 @@ + else + { + struct undo_replace_buff_elem *reg_move_replaces; +- int amount; +- +- /* Set the stage boundaries. If the DDG is built with closing_branch_deps, +- the closing_branch was scheduled and should appear in the last (ii-1) +- row. Otherwise, we are free to schedule the branch, and we let nodes +- that were scheduled at the first PS_MIN_CYCLE cycle appear in the first +- row; this should reduce stage_count to minimum. +- TODO: Revisit the issue of scheduling the insns of the +- control part relative to the branch when the control part +- has more than one insn. */ +- amount = (g->closing_branch_deps)? SCHED_TIME (g->closing_branch) + 1: +- PS_MIN_CYCLE (ps); ++ int amount = SCHED_TIME (g->closing_branch) + 1; ++ ++ /* Set the stage boundaries. The closing_branch was scheduled ++ and should appear in the last (ii-1) row. */ + reset_sched_times (ps, amount); + rotate_partial_schedule (ps, amount); +- + set_columns_for_ps (ps); + + canon_loop (loop); +@@ -1267,13 +1237,8 @@ + "SMS succeeded %d %d (with ii, sc)\n", ps->ii, + stage_count); + print_partial_schedule (ps, dump_file); +- if (!g->closing_branch_deps) +- fprintf (dump_file, +- "SMS Branch (%d) will later be scheduled at \ +- cycle %d.\n", +- g->closing_branch->cuid, PS_MIN_CYCLE (ps) - 1); +- } +- ++ } ++ + /* case the BCT count is not known , Do loop-versioning */ + if (count_reg && ! count_init) + { +@@ -1318,7 +1283,6 @@ + } + + free (g_arr); +- sbitmap_free (doloop_insns); + + /* Release scheduler data, needed until now because of DFA. */ + haifa_sched_finish (); +@@ -1826,13 +1790,6 @@ + RESET_BIT (tobe_scheduled, u); + continue; + } +- /* Closing branch handled later unless closing_branch_deps +- is true. */ +- if (JUMP_P (insn) && !g->closing_branch_deps) +- { +- RESET_BIT (tobe_scheduled, u); +- continue; +- } + + if (TEST_BIT (sched_nodes, u)) + continue; +@@ -2675,9 +2632,9 @@ + last_in_row = next_ps_i; + } + +- /* If closing_branch_deps is true we are scheduling the closing +- branch as well. Make sure there is no dependent instruction after +- it as the branch should be the last instruction. */ ++ /* The closing branch is scheduled as well. Make sure there is no ++ dependent instruction after it as the branch should be the last ++ instruction in the row. */ + if (JUMP_P (ps_i->node->insn)) + { + if (first_must_follow) +@@ -2918,51 +2875,21 @@ + return ps_i; + } + +-/* Calculate the stage count of the partial schedule PS. */ ++/* Calculate the stage count of the partial schedule PS. The calculation ++ takes into account the rotation to bring the closing branch to row ++ ii-1. */ + int + calculate_stage_count (partial_schedule_ptr ps) + { +- int stage_count; +- +- /* If closing_branch_deps is false then the stage +- boundaries are placed efficiently, meaning that min_cycle will be +- placed at row 0. Otherwise, the closing branch will be placed in +- row ii-1. For the later case we assume the final SMSed kernel can +- be divided into two intervals. This assumption is used for the +- stage count calculation: +- +- 1) min_cycle <= interval 0 < first_cycle_in_row_zero +- 2) first_cycle_in_row_zero <= interval 1 < max_cycle +- */ +- stage_count = +- CALC_STAGE_COUNT (PS_MIN_CYCLE (ps), PS_MAX_CYCLE (ps), ps->ii); +- if (ps->g->closing_branch_deps) +- { +- int new_min_cycle; +- int new_min_cycle_row; +- int rotation_amount = SCHED_TIME (ps->g->closing_branch) + 1; +- +- /* This is the new value of min_cycle after the final rotation to +- bring closing branch into row ii-1. */ +- new_min_cycle = PS_MIN_CYCLE (ps) - rotation_amount; +- /* This is the row which the the new min_cycle will be placed in. */ +- new_min_cycle_row = SMODULO (new_min_cycle, ps->ii); +- /* If the row of min_cycle is zero then interval 0 is empty. +- Otherwise, we need to calculate interval 1 and add it by one +- to take interval 0 into account. */ +- if (new_min_cycle_row != 0) +- { +- int new_max_cycle, first_cycle_in_row_zero; +- +- new_max_cycle = PS_MAX_CYCLE (ps) - rotation_amount; +- first_cycle_in_row_zero = +- new_min_cycle + ps->ii - new_min_cycle_row; +- +- stage_count = +- CALC_STAGE_COUNT (first_cycle_in_row_zero, new_max_cycle, +- ps->ii) + 1; +- } +- } ++ int rotation_amount = (SCHED_TIME (ps->g->closing_branch)) + 1; ++ int new_min_cycle = PS_MIN_CYCLE (ps) - rotation_amount; ++ int new_max_cycle = PS_MAX_CYCLE (ps) - rotation_amount; ++ int stage_count = CALC_STAGE_COUNT (-1, new_min_cycle, ps->ii); ++ ++ /* The calculation of stage count is done adding the number of stages ++ before cycle zero and after cycle zero. */ ++ stage_count += CALC_STAGE_COUNT (new_max_cycle, 0, ps->ii); ++ + return stage_count; + } + + +=== modified file 'gcc/params.def' +--- old/gcc/params.def 2011-02-01 14:20:13 +0000 ++++ new/gcc/params.def 2011-05-11 08:00:14 +0000 +@@ -324,6 +324,11 @@ + "sms-max-ii-factor", + "A factor for tuning the upper bound that swing modulo scheduler uses for scheduling a loop", + 100, 0, 0) ++/* The minimum value of stage count that swing modulo scheduler will generate. */ ++DEFPARAM(PARAM_SMS_MIN_SC, ++ "sms-min-sc", ++ "The minimum value of stage count that swing modulo scheduler will generate.", ++ 2, 1, 1) + DEFPARAM(PARAM_SMS_DFA_HISTORY, + "sms-dfa-history", + "The number of cycles the swing modulo scheduler considers when checking conflicts using DFA", + |