diff options
Diffstat (limited to 'meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99511.patch')
| -rw-r--r-- | meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99511.patch | 582 |
1 files changed, 582 insertions, 0 deletions
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99511.patch b/meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99511.patch new file mode 100644 index 0000000000..8d096c25d0 --- /dev/null +++ b/meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99511.patch | |||
| @@ -0,0 +1,582 @@ | |||
| 1 | 2011-05-13 Revital Eres <revital.eres@linaro.org> | ||
| 2 | |||
| 3 | gcc/ | ||
| 4 | * loop-doloop.c (doloop_condition_get): Support new form of | ||
| 5 | doloop pattern and use prev_nondebug_insn instead of PREV_INSN. | ||
| 6 | * config/arm/thumb2.md (*thumb2_addsi3_compare0): Remove "*". | ||
| 7 | (doloop_end): New. | ||
| 8 | * config/arm/arm.md (*addsi3_compare0): Remove "*". | ||
| 9 | * params.def (sms-min-sc): New param flag. | ||
| 10 | * doc/invoke.texi (sms-min-sc): Document it. | ||
| 11 | * ddg.c (create_ddg_dep_from_intra_loop_link): If a true dep edge | ||
| 12 | enters the branch create an anti edge in the opposite direction | ||
| 13 | to prevent the creation of reg-moves. | ||
| 14 | (get_node_of_insn_uid, check_closing_branch_deps): Delete | ||
| 15 | functions. | ||
| 16 | (create_ddg): Restore previous definition and implementation. | ||
| 17 | * ddg.h (create_ddg): Restore previous definition. | ||
| 18 | * modulo-sched.c: Adjust comment to reflect the fact we are | ||
| 19 | scheduling closing branch. | ||
| 20 | (PS_STAGE_COUNT): Rename to CALC_STAGE_COUNT and redefine. | ||
| 21 | (stage_count): New field in struct partial_schedule. | ||
| 22 | (calculate_stage_count): New function. | ||
| 23 | (normalize_sched_times): Rename to reset_sched_times and handle | ||
| 24 | incrementing the sched time of the nodes by a constant value | ||
| 25 | passed as parameter. | ||
| 26 | (duplicate_insns_of_cycles): Skip closing branch. | ||
| 27 | (sms_schedule_by_order): Schedule closing branch. | ||
| 28 | (ps_insn_find_column): Handle closing branch. | ||
| 29 | (sms_schedule): Call reset_sched_times and adjust the code to | ||
| 30 | support scheduling of the closing branch. Use sms-min-sc. | ||
| 31 | Support new form of doloop pattern. | ||
| 32 | (ps_insert_empty_row): Update calls to normalize_sched_times | ||
| 33 | and rotate_partial_schedule functions. | ||
| 34 | (mark_doloop_insns): Remove. | ||
| 35 | |||
| 36 | === modified file 'gcc/ddg.c' | ||
| 37 | --- old/gcc/ddg.c 2011-03-24 07:45:38 +0000 | ||
| 38 | +++ new/gcc/ddg.c 2011-05-11 08:00:14 +0000 | ||
| 39 | @@ -60,8 +60,6 @@ | ||
| 40 | static ddg_edge_ptr create_ddg_edge (ddg_node_ptr, ddg_node_ptr, dep_type, | ||
| 41 | dep_data_type, int, int); | ||
| 42 | static void add_edge_to_ddg (ddg_ptr g, ddg_edge_ptr); | ||
| 43 | -static ddg_node_ptr get_node_of_insn_uid (ddg_ptr, int); | ||
| 44 | - | ||
| 45 | |||
| 46 | /* Auxiliary variable for mem_read_insn_p/mem_write_insn_p. */ | ||
| 47 | static bool mem_ref_p; | ||
| 48 | @@ -199,6 +197,11 @@ | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
| 52 | + /* If a true dep edge enters the branch create an anti edge in the | ||
| 53 | + opposite direction to prevent the creation of reg-moves. */ | ||
| 54 | + if ((DEP_TYPE (link) == REG_DEP_TRUE) && JUMP_P (dest_node->insn)) | ||
| 55 | + create_ddg_dep_no_link (g, dest_node, src_node, ANTI_DEP, REG_DEP, 1); | ||
| 56 | + | ||
| 57 | latency = dep_cost (link); | ||
| 58 | e = create_ddg_edge (src_node, dest_node, t, dt, latency, distance); | ||
| 59 | add_edge_to_ddg (g, e); | ||
| 60 | @@ -452,65 +455,12 @@ | ||
| 61 | sched_free_deps (head, tail, false); | ||
| 62 | } | ||
| 63 | |||
| 64 | -/* Given DOLOOP_INSNS which holds the instructions that | ||
| 65 | - belong to the do-loop part; mark closing_branch_deps field in ddg G | ||
| 66 | - as TRUE if the do-loop part's instructions are dependent on the other | ||
| 67 | - loop instructions. Otherwise mark it as FALSE. */ | ||
| 68 | -static void | ||
| 69 | -check_closing_branch_deps (ddg_ptr g, sbitmap doloop_insns) | ||
| 70 | -{ | ||
| 71 | - sbitmap_iterator sbi; | ||
| 72 | - unsigned int u = 0; | ||
| 73 | - | ||
| 74 | - EXECUTE_IF_SET_IN_SBITMAP (doloop_insns, 0, u, sbi) | ||
| 75 | - { | ||
| 76 | - ddg_edge_ptr e; | ||
| 77 | - ddg_node_ptr u_node = get_node_of_insn_uid (g, u); | ||
| 78 | - | ||
| 79 | - gcc_assert (u_node); | ||
| 80 | - | ||
| 81 | - for (e = u_node->in; e != 0; e = e->next_in) | ||
| 82 | - { | ||
| 83 | - ddg_node_ptr v_node = e->src; | ||
| 84 | - | ||
| 85 | - if (((unsigned int) INSN_UID (v_node->insn) == u) | ||
| 86 | - || DEBUG_INSN_P (v_node->insn)) | ||
| 87 | - continue; | ||
| 88 | - | ||
| 89 | - /* Ignore dependencies between memory writes and the | ||
| 90 | - jump. */ | ||
| 91 | - if (JUMP_P (u_node->insn) | ||
| 92 | - && e->type == OUTPUT_DEP | ||
| 93 | - && mem_write_insn_p (v_node->insn)) | ||
| 94 | - continue; | ||
| 95 | - if (!TEST_BIT (doloop_insns, INSN_UID (v_node->insn))) | ||
| 96 | - { | ||
| 97 | - g->closing_branch_deps = 1; | ||
| 98 | - return; | ||
| 99 | - } | ||
| 100 | - } | ||
| 101 | - for (e = u_node->out; e != 0; e = e->next_out) | ||
| 102 | - { | ||
| 103 | - ddg_node_ptr v_node = e->dest; | ||
| 104 | - | ||
| 105 | - if (((unsigned int) INSN_UID (v_node->insn) == u) | ||
| 106 | - || DEBUG_INSN_P (v_node->insn)) | ||
| 107 | - continue; | ||
| 108 | - if (!TEST_BIT (doloop_insns, INSN_UID (v_node->insn))) | ||
| 109 | - { | ||
| 110 | - g->closing_branch_deps = 1; | ||
| 111 | - return; | ||
| 112 | - } | ||
| 113 | - } | ||
| 114 | - } | ||
| 115 | - g->closing_branch_deps = 0; | ||
| 116 | -} | ||
| 117 | |||
| 118 | /* Given a basic block, create its DDG and return a pointer to a variable | ||
| 119 | of ddg type that represents it. | ||
| 120 | Initialize the ddg structure fields to the appropriate values. */ | ||
| 121 | ddg_ptr | ||
| 122 | -create_ddg (basic_block bb, sbitmap doloop_insns) | ||
| 123 | +create_ddg (basic_block bb, int closing_branch_deps) | ||
| 124 | { | ||
| 125 | ddg_ptr g; | ||
| 126 | rtx insn, first_note; | ||
| 127 | @@ -520,6 +470,7 @@ | ||
| 128 | g = (ddg_ptr) xcalloc (1, sizeof (struct ddg)); | ||
| 129 | |||
| 130 | g->bb = bb; | ||
| 131 | + g->closing_branch_deps = closing_branch_deps; | ||
| 132 | |||
| 133 | /* Count the number of insns in the BB. */ | ||
| 134 | for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb)); | ||
| 135 | @@ -592,11 +543,6 @@ | ||
| 136 | /* Build the data dependency graph. */ | ||
| 137 | build_intra_loop_deps (g); | ||
| 138 | build_inter_loop_deps (g); | ||
| 139 | - | ||
| 140 | - /* Check whether the do-loop part is decoupled from the other loop | ||
| 141 | - instructions. */ | ||
| 142 | - check_closing_branch_deps (g, doloop_insns); | ||
| 143 | - | ||
| 144 | return g; | ||
| 145 | } | ||
| 146 | |||
| 147 | @@ -890,18 +836,6 @@ | ||
| 148 | return NULL; | ||
| 149 | } | ||
| 150 | |||
| 151 | -/* Given the uid of an instruction UID return the node that represents it. */ | ||
| 152 | -static ddg_node_ptr | ||
| 153 | -get_node_of_insn_uid (ddg_ptr g, int uid) | ||
| 154 | -{ | ||
| 155 | - int i; | ||
| 156 | - | ||
| 157 | - for (i = 0; i < g->num_nodes; i++) | ||
| 158 | - if (uid == INSN_UID (g->nodes[i].insn)) | ||
| 159 | - return &g->nodes[i]; | ||
| 160 | - return NULL; | ||
| 161 | -} | ||
| 162 | - | ||
| 163 | /* Given a set OPS of nodes in the DDG, find the set of their successors | ||
| 164 | which are not in OPS, and set their bits in SUCC. Bits corresponding to | ||
| 165 | OPS are cleared from SUCC. Leaves the other bits in SUCC unchanged. */ | ||
| 166 | |||
| 167 | === modified file 'gcc/ddg.h' | ||
| 168 | --- old/gcc/ddg.h 2011-03-24 07:45:38 +0000 | ||
| 169 | +++ new/gcc/ddg.h 2011-05-11 08:00:14 +0000 | ||
| 170 | @@ -167,7 +167,7 @@ | ||
| 171 | }; | ||
| 172 | |||
| 173 | |||
| 174 | -ddg_ptr create_ddg (basic_block, sbitmap); | ||
| 175 | +ddg_ptr create_ddg (basic_block, int closing_branch_deps); | ||
| 176 | void free_ddg (ddg_ptr); | ||
| 177 | |||
| 178 | void print_ddg (FILE *, ddg_ptr); | ||
| 179 | |||
| 180 | === modified file 'gcc/doc/invoke.texi' | ||
| 181 | --- old/gcc/doc/invoke.texi 2011-04-17 23:04:58 +0000 | ||
| 182 | +++ new/gcc/doc/invoke.texi 2011-05-11 08:00:14 +0000 | ||
| 183 | @@ -8430,6 +8430,10 @@ | ||
| 184 | The maximum number of best instructions in the ready list that are considered | ||
| 185 | for renaming in the selective scheduler. The default value is 2. | ||
| 186 | |||
| 187 | +@item sms-min-sc | ||
| 188 | +The minimum value of stage count that swing modulo scheduler will | ||
| 189 | +generate. The default value is 2. | ||
| 190 | + | ||
| 191 | @item max-last-value-rtl | ||
| 192 | The maximum size measured as number of RTLs that can be recorded in an expression | ||
| 193 | in combiner for a pseudo register as last known value of that register. The default | ||
| 194 | |||
| 195 | === modified file 'gcc/modulo-sched.c' | ||
| 196 | --- old/gcc/modulo-sched.c 2011-03-24 07:45:38 +0000 | ||
| 197 | +++ new/gcc/modulo-sched.c 2011-05-11 08:00:14 +0000 | ||
| 198 | @@ -84,14 +84,13 @@ | ||
| 199 | II cycles (i.e. use register copies to prevent a def from overwriting | ||
| 200 | itself before reaching the use). | ||
| 201 | |||
| 202 | - SMS works with countable loops (1) whose control part can be easily | ||
| 203 | - decoupled from the rest of the loop and (2) whose loop count can | ||
| 204 | - be easily adjusted. This is because we peel a constant number of | ||
| 205 | - iterations into a prologue and epilogue for which we want to avoid | ||
| 206 | - emitting the control part, and a kernel which is to iterate that | ||
| 207 | - constant number of iterations less than the original loop. So the | ||
| 208 | - control part should be a set of insns clearly identified and having | ||
| 209 | - its own iv, not otherwise used in the loop (at-least for now), which | ||
| 210 | + SMS works with countable loops whose loop count can be easily | ||
| 211 | + adjusted. This is because we peel a constant number of iterations | ||
| 212 | + into a prologue and epilogue for which we want to avoid emitting | ||
| 213 | + the control part, and a kernel which is to iterate that constant | ||
| 214 | + number of iterations less than the original loop. So the control | ||
| 215 | + part should be a set of insns clearly identified and having its | ||
| 216 | + own iv, not otherwise used in the loop (at-least for now), which | ||
| 217 | initializes a register before the loop to the number of iterations. | ||
| 218 | Currently SMS relies on the do-loop pattern to recognize such loops, | ||
| 219 | where (1) the control part comprises of all insns defining and/or | ||
| 220 | @@ -116,7 +115,7 @@ | ||
| 221 | |||
| 222 | /* The number of different iterations the nodes in ps span, assuming | ||
| 223 | the stage boundaries are placed efficiently. */ | ||
| 224 | -#define CALC_STAGE_COUNT(min_cycle,max_cycle,ii) ((max_cycle - min_cycle \ | ||
| 225 | +#define CALC_STAGE_COUNT(max_cycle,min_cycle,ii) ((max_cycle - min_cycle \ | ||
| 226 | + 1 + ii - 1) / ii) | ||
| 227 | /* The stage count of ps. */ | ||
| 228 | #define PS_STAGE_COUNT(ps) (((partial_schedule_ptr)(ps))->stage_count) | ||
| 229 | @@ -200,7 +199,6 @@ | ||
| 230 | static void duplicate_insns_of_cycles (partial_schedule_ptr, | ||
| 231 | int, int, int, rtx); | ||
| 232 | static int calculate_stage_count (partial_schedule_ptr ps); | ||
| 233 | - | ||
| 234 | #define SCHED_ASAP(x) (((node_sched_params_ptr)(x)->aux.info)->asap) | ||
| 235 | #define SCHED_TIME(x) (((node_sched_params_ptr)(x)->aux.info)->time) | ||
| 236 | #define SCHED_FIRST_REG_MOVE(x) \ | ||
| 237 | @@ -318,7 +316,7 @@ | ||
| 238 | : prev_nondebug_insn (tail)); | ||
| 239 | |||
| 240 | for (insn = head; insn != first_insn_not_to_check; insn = NEXT_INSN (insn)) | ||
| 241 | - if (reg_mentioned_p (reg, insn) && NONDEBUG_INSN_P (insn)) | ||
| 242 | + if (reg_mentioned_p (reg, insn) && !DEBUG_INSN_P (insn)) | ||
| 243 | { | ||
| 244 | if (dump_file) | ||
| 245 | { | ||
| 246 | @@ -337,24 +335,6 @@ | ||
| 247 | #endif | ||
| 248 | } | ||
| 249 | |||
| 250 | -/* Mark in DOLOOP_INSNS the instructions that belong to the do-loop part. | ||
| 251 | - Use TAIL to recognize that part. */ | ||
| 252 | -static void | ||
| 253 | -mark_doloop_insns (sbitmap doloop_insns, rtx tail) | ||
| 254 | -{ | ||
| 255 | - rtx first_insn_not_to_check, insn; | ||
| 256 | - | ||
| 257 | - /* This is the first instruction which belongs the doloop part. */ | ||
| 258 | - first_insn_not_to_check = (GET_CODE (PATTERN (tail)) == PARALLEL ? tail | ||
| 259 | - : prev_nondebug_insn (tail)); | ||
| 260 | - | ||
| 261 | - sbitmap_zero (doloop_insns); | ||
| 262 | - for (insn = first_insn_not_to_check; insn != NEXT_INSN (tail); | ||
| 263 | - insn = NEXT_INSN (insn)) | ||
| 264 | - if (NONDEBUG_INSN_P (insn)) | ||
| 265 | - SET_BIT (doloop_insns, INSN_UID (insn)); | ||
| 266 | -} | ||
| 267 | - | ||
| 268 | /* Check if COUNT_REG is set to a constant in the PRE_HEADER block, so | ||
| 269 | that the number of iterations is a compile-time constant. If so, | ||
| 270 | return the rtx that sets COUNT_REG to a constant, and set COUNT to | ||
| 271 | @@ -607,44 +587,42 @@ | ||
| 272 | ddg_node_ptr u = crr_insn->node; | ||
| 273 | int normalized_time = SCHED_TIME (u) - amount; | ||
| 274 | int new_min_cycle = PS_MIN_CYCLE (ps) - amount; | ||
| 275 | - /* The first cycle in row zero after the rotation. */ | ||
| 276 | - int new_first_cycle_in_row_zero = | ||
| 277 | - new_min_cycle + ii - SMODULO (new_min_cycle, ii); | ||
| 278 | + int sc_until_cycle_zero, stage; | ||
| 279 | |||
| 280 | - if (dump_file) | ||
| 281 | - fprintf (dump_file, "crr_insn->node=%d, crr_insn->cycle=%d,\ | ||
| 282 | - min_cycle=%d\n", crr_insn->node->cuid, SCHED_TIME | ||
| 283 | - (u), ps->min_cycle); | ||
| 284 | + if (dump_file) | ||
| 285 | + { | ||
| 286 | + /* Print the scheduling times after the rotation. */ | ||
| 287 | + fprintf (dump_file, "crr_insn->node=%d (insn id %d), " | ||
| 288 | + "crr_insn->cycle=%d, min_cycle=%d", crr_insn->node->cuid, | ||
| 289 | + INSN_UID (crr_insn->node->insn), SCHED_TIME (u), | ||
| 290 | + normalized_time); | ||
| 291 | + if (JUMP_P (crr_insn->node->insn)) | ||
| 292 | + fprintf (dump_file, " (branch)"); | ||
| 293 | + fprintf (dump_file, "\n"); | ||
| 294 | + } | ||
| 295 | + | ||
| 296 | gcc_assert (SCHED_TIME (u) >= ps->min_cycle); | ||
| 297 | gcc_assert (SCHED_TIME (u) <= ps->max_cycle); | ||
| 298 | SCHED_TIME (u) = normalized_time; | ||
| 299 | - crr_insn->cycle = normalized_time; | ||
| 300 | SCHED_ROW (u) = SMODULO (normalized_time, ii); | ||
| 301 | - | ||
| 302 | - /* If min_cycle is in row zero after the rotation then | ||
| 303 | - the stage count can be calculated by dividing the cycle | ||
| 304 | - with ii. Otherwise, the calculation is done by dividing the | ||
| 305 | - SMSed kernel into two intervals: | ||
| 306 | - | ||
| 307 | - 1) min_cycle <= interval 0 < first_cycle_in_row_zero | ||
| 308 | - 2) first_cycle_in_row_zero <= interval 1 < max_cycle | ||
| 309 | - | ||
| 310 | - Cycles in interval 0 are in stage 0. The stage of cycles | ||
| 311 | - in interval 1 should be added by 1 to take interval 0 into | ||
| 312 | - account. */ | ||
| 313 | - if (SMODULO (new_min_cycle, ii) == 0) | ||
| 314 | - SCHED_STAGE (u) = normalized_time / ii; | ||
| 315 | - else | ||
| 316 | - { | ||
| 317 | - if (crr_insn->cycle < new_first_cycle_in_row_zero) | ||
| 318 | - SCHED_STAGE (u) = 0; | ||
| 319 | - else | ||
| 320 | - SCHED_STAGE (u) = | ||
| 321 | - ((SCHED_TIME (u) - new_first_cycle_in_row_zero) / ii) + 1; | ||
| 322 | + | ||
| 323 | + /* The calculation of stage count is done adding the number | ||
| 324 | + of stages before cycle zero and after cycle zero. */ | ||
| 325 | + sc_until_cycle_zero = CALC_STAGE_COUNT (-1, new_min_cycle, ii); | ||
| 326 | + | ||
| 327 | + if (SCHED_TIME (u) < 0) | ||
| 328 | + { | ||
| 329 | + stage = CALC_STAGE_COUNT (-1, SCHED_TIME (u), ii); | ||
| 330 | + SCHED_STAGE (u) = sc_until_cycle_zero - stage; | ||
| 331 | + } | ||
| 332 | + else | ||
| 333 | + { | ||
| 334 | + stage = CALC_STAGE_COUNT (SCHED_TIME (u), 0, ii); | ||
| 335 | + SCHED_STAGE (u) = sc_until_cycle_zero + stage - 1; | ||
| 336 | } | ||
| 337 | } | ||
| 338 | } | ||
| 339 | - | ||
| 340 | + | ||
| 341 | /* Set SCHED_COLUMN of each node according to its position in PS. */ | ||
| 342 | static void | ||
| 343 | set_columns_for_ps (partial_schedule_ptr ps) | ||
| 344 | @@ -694,8 +672,8 @@ | ||
| 345 | |||
| 346 | /* Do not duplicate any insn which refers to count_reg as it | ||
| 347 | belongs to the control part. | ||
| 348 | - If closing_branch_deps is true the closing branch is scheduled | ||
| 349 | - as well and thus should be ignored. | ||
| 350 | + The closing branch is scheduled as well and thus should | ||
| 351 | + be ignored. | ||
| 352 | TODO: This should be done by analyzing the control part of | ||
| 353 | the loop. */ | ||
| 354 | if (reg_mentioned_p (count_reg, u_node->insn) | ||
| 355 | @@ -945,8 +923,7 @@ | ||
| 356 | basic_block condition_bb = NULL; | ||
| 357 | edge latch_edge; | ||
| 358 | gcov_type trip_count = 0; | ||
| 359 | - sbitmap doloop_insns; | ||
| 360 | - | ||
| 361 | + | ||
| 362 | loop_optimizer_init (LOOPS_HAVE_PREHEADERS | ||
| 363 | | LOOPS_HAVE_RECORDED_EXITS); | ||
| 364 | if (number_of_loops () <= 1) | ||
| 365 | @@ -971,7 +948,6 @@ | ||
| 366 | setup_sched_infos (); | ||
| 367 | haifa_sched_init (); | ||
| 368 | |||
| 369 | - doloop_insns = sbitmap_alloc (get_max_uid () + 1); | ||
| 370 | /* Allocate memory to hold the DDG array one entry for each loop. | ||
| 371 | We use loop->num as index into this array. */ | ||
| 372 | g_arr = XCNEWVEC (ddg_ptr, number_of_loops ()); | ||
| 373 | @@ -1104,16 +1080,18 @@ | ||
| 374 | |||
| 375 | continue; | ||
| 376 | } | ||
| 377 | - mark_doloop_insns (doloop_insns, tail); | ||
| 378 | - if (! (g = create_ddg (bb, doloop_insns))) | ||
| 379 | + | ||
| 380 | + /* Always schedule the closing branch with the rest of the | ||
| 381 | + instructions. The branch is rotated to be in row ii-1 at the | ||
| 382 | + end of the scheduling procedure to make sure it's the last | ||
| 383 | + instruction in the iteration. */ | ||
| 384 | + if (! (g = create_ddg (bb, 1))) | ||
| 385 | { | ||
| 386 | if (dump_file) | ||
| 387 | fprintf (dump_file, "SMS create_ddg failed\n"); | ||
| 388 | continue; | ||
| 389 | } | ||
| 390 | - if (dump_file) | ||
| 391 | - fprintf (dump_file, "SMS closing_branch_deps: %d\n", | ||
| 392 | - g->closing_branch_deps); | ||
| 393 | + | ||
| 394 | g_arr[loop->num] = g; | ||
| 395 | if (dump_file) | ||
| 396 | fprintf (dump_file, "...OK\n"); | ||
| 397 | @@ -1215,16 +1193,17 @@ | ||
| 398 | |||
| 399 | ps = sms_schedule_by_order (g, mii, maxii, node_order); | ||
| 400 | |||
| 401 | - if (ps) | ||
| 402 | - { | ||
| 403 | - stage_count = calculate_stage_count (ps); | ||
| 404 | - gcc_assert(stage_count >= 1); | ||
| 405 | - PS_STAGE_COUNT(ps) = stage_count; | ||
| 406 | - } | ||
| 407 | - | ||
| 408 | - /* Stage count of 1 means that there is no interleaving between | ||
| 409 | - iterations, let the scheduling passes do the job. */ | ||
| 410 | - if (stage_count <= 1 | ||
| 411 | + if (ps) | ||
| 412 | + { | ||
| 413 | + stage_count = calculate_stage_count (ps); | ||
| 414 | + gcc_assert(stage_count >= 1); | ||
| 415 | + PS_STAGE_COUNT(ps) = stage_count; | ||
| 416 | + } | ||
| 417 | + | ||
| 418 | + /* The default value of PARAM_SMS_MIN_SC is 2 as stage count of | ||
| 419 | + 1 means that there is no interleaving between iterations thus | ||
| 420 | + we let the scheduling passes do the job in this case. */ | ||
| 421 | + if (stage_count < (unsigned) PARAM_VALUE (PARAM_SMS_MIN_SC) | ||
| 422 | || (count_init && (loop_count <= stage_count)) | ||
| 423 | || (flag_branch_probabilities && (trip_count <= stage_count))) | ||
| 424 | { | ||
| 425 | @@ -1242,21 +1221,12 @@ | ||
| 426 | else | ||
| 427 | { | ||
| 428 | struct undo_replace_buff_elem *reg_move_replaces; | ||
| 429 | - int amount; | ||
| 430 | - | ||
| 431 | - /* Set the stage boundaries. If the DDG is built with closing_branch_deps, | ||
| 432 | - the closing_branch was scheduled and should appear in the last (ii-1) | ||
| 433 | - row. Otherwise, we are free to schedule the branch, and we let nodes | ||
| 434 | - that were scheduled at the first PS_MIN_CYCLE cycle appear in the first | ||
| 435 | - row; this should reduce stage_count to minimum. | ||
| 436 | - TODO: Revisit the issue of scheduling the insns of the | ||
| 437 | - control part relative to the branch when the control part | ||
| 438 | - has more than one insn. */ | ||
| 439 | - amount = (g->closing_branch_deps)? SCHED_TIME (g->closing_branch) + 1: | ||
| 440 | - PS_MIN_CYCLE (ps); | ||
| 441 | + int amount = SCHED_TIME (g->closing_branch) + 1; | ||
| 442 | + | ||
| 443 | + /* Set the stage boundaries. The closing_branch was scheduled | ||
| 444 | + and should appear in the last (ii-1) row. */ | ||
| 445 | reset_sched_times (ps, amount); | ||
| 446 | rotate_partial_schedule (ps, amount); | ||
| 447 | - | ||
| 448 | set_columns_for_ps (ps); | ||
| 449 | |||
| 450 | canon_loop (loop); | ||
| 451 | @@ -1267,13 +1237,8 @@ | ||
| 452 | "SMS succeeded %d %d (with ii, sc)\n", ps->ii, | ||
| 453 | stage_count); | ||
| 454 | print_partial_schedule (ps, dump_file); | ||
| 455 | - if (!g->closing_branch_deps) | ||
| 456 | - fprintf (dump_file, | ||
| 457 | - "SMS Branch (%d) will later be scheduled at \ | ||
| 458 | - cycle %d.\n", | ||
| 459 | - g->closing_branch->cuid, PS_MIN_CYCLE (ps) - 1); | ||
| 460 | - } | ||
| 461 | - | ||
| 462 | + } | ||
| 463 | + | ||
| 464 | /* case the BCT count is not known , Do loop-versioning */ | ||
| 465 | if (count_reg && ! count_init) | ||
| 466 | { | ||
| 467 | @@ -1318,7 +1283,6 @@ | ||
| 468 | } | ||
| 469 | |||
| 470 | free (g_arr); | ||
| 471 | - sbitmap_free (doloop_insns); | ||
| 472 | |||
| 473 | /* Release scheduler data, needed until now because of DFA. */ | ||
| 474 | haifa_sched_finish (); | ||
| 475 | @@ -1826,13 +1790,6 @@ | ||
| 476 | RESET_BIT (tobe_scheduled, u); | ||
| 477 | continue; | ||
| 478 | } | ||
| 479 | - /* Closing branch handled later unless closing_branch_deps | ||
| 480 | - is true. */ | ||
| 481 | - if (JUMP_P (insn) && !g->closing_branch_deps) | ||
| 482 | - { | ||
| 483 | - RESET_BIT (tobe_scheduled, u); | ||
| 484 | - continue; | ||
| 485 | - } | ||
| 486 | |||
| 487 | if (TEST_BIT (sched_nodes, u)) | ||
| 488 | continue; | ||
| 489 | @@ -2675,9 +2632,9 @@ | ||
| 490 | last_in_row = next_ps_i; | ||
| 491 | } | ||
| 492 | |||
| 493 | - /* If closing_branch_deps is true we are scheduling the closing | ||
| 494 | - branch as well. Make sure there is no dependent instruction after | ||
| 495 | - it as the branch should be the last instruction. */ | ||
| 496 | + /* The closing branch is scheduled as well. Make sure there is no | ||
| 497 | + dependent instruction after it as the branch should be the last | ||
| 498 | + instruction in the row. */ | ||
| 499 | if (JUMP_P (ps_i->node->insn)) | ||
| 500 | { | ||
| 501 | if (first_must_follow) | ||
| 502 | @@ -2918,51 +2875,21 @@ | ||
| 503 | return ps_i; | ||
| 504 | } | ||
| 505 | |||
| 506 | -/* Calculate the stage count of the partial schedule PS. */ | ||
| 507 | +/* Calculate the stage count of the partial schedule PS. The calculation | ||
| 508 | + takes into account the rotation to bring the closing branch to row | ||
| 509 | + ii-1. */ | ||
| 510 | int | ||
| 511 | calculate_stage_count (partial_schedule_ptr ps) | ||
| 512 | { | ||
| 513 | - int stage_count; | ||
| 514 | - | ||
| 515 | - /* If closing_branch_deps is false then the stage | ||
| 516 | - boundaries are placed efficiently, meaning that min_cycle will be | ||
| 517 | - placed at row 0. Otherwise, the closing branch will be placed in | ||
| 518 | - row ii-1. For the later case we assume the final SMSed kernel can | ||
| 519 | - be divided into two intervals. This assumption is used for the | ||
| 520 | - stage count calculation: | ||
| 521 | - | ||
| 522 | - 1) min_cycle <= interval 0 < first_cycle_in_row_zero | ||
| 523 | - 2) first_cycle_in_row_zero <= interval 1 < max_cycle | ||
| 524 | - */ | ||
| 525 | - stage_count = | ||
| 526 | - CALC_STAGE_COUNT (PS_MIN_CYCLE (ps), PS_MAX_CYCLE (ps), ps->ii); | ||
| 527 | - if (ps->g->closing_branch_deps) | ||
| 528 | - { | ||
| 529 | - int new_min_cycle; | ||
| 530 | - int new_min_cycle_row; | ||
| 531 | - int rotation_amount = SCHED_TIME (ps->g->closing_branch) + 1; | ||
| 532 | - | ||
| 533 | - /* This is the new value of min_cycle after the final rotation to | ||
| 534 | - bring closing branch into row ii-1. */ | ||
| 535 | - new_min_cycle = PS_MIN_CYCLE (ps) - rotation_amount; | ||
| 536 | - /* This is the row which the the new min_cycle will be placed in. */ | ||
| 537 | - new_min_cycle_row = SMODULO (new_min_cycle, ps->ii); | ||
| 538 | - /* If the row of min_cycle is zero then interval 0 is empty. | ||
| 539 | - Otherwise, we need to calculate interval 1 and add it by one | ||
| 540 | - to take interval 0 into account. */ | ||
| 541 | - if (new_min_cycle_row != 0) | ||
| 542 | - { | ||
| 543 | - int new_max_cycle, first_cycle_in_row_zero; | ||
| 544 | - | ||
| 545 | - new_max_cycle = PS_MAX_CYCLE (ps) - rotation_amount; | ||
| 546 | - first_cycle_in_row_zero = | ||
| 547 | - new_min_cycle + ps->ii - new_min_cycle_row; | ||
| 548 | - | ||
| 549 | - stage_count = | ||
| 550 | - CALC_STAGE_COUNT (first_cycle_in_row_zero, new_max_cycle, | ||
| 551 | - ps->ii) + 1; | ||
| 552 | - } | ||
| 553 | - } | ||
| 554 | + int rotation_amount = (SCHED_TIME (ps->g->closing_branch)) + 1; | ||
| 555 | + int new_min_cycle = PS_MIN_CYCLE (ps) - rotation_amount; | ||
| 556 | + int new_max_cycle = PS_MAX_CYCLE (ps) - rotation_amount; | ||
| 557 | + int stage_count = CALC_STAGE_COUNT (-1, new_min_cycle, ps->ii); | ||
| 558 | + | ||
| 559 | + /* The calculation of stage count is done adding the number of stages | ||
| 560 | + before cycle zero and after cycle zero. */ | ||
| 561 | + stage_count += CALC_STAGE_COUNT (new_max_cycle, 0, ps->ii); | ||
| 562 | + | ||
| 563 | return stage_count; | ||
| 564 | } | ||
| 565 | |||
| 566 | |||
| 567 | === modified file 'gcc/params.def' | ||
| 568 | --- old/gcc/params.def 2011-02-01 14:20:13 +0000 | ||
| 569 | +++ new/gcc/params.def 2011-05-11 08:00:14 +0000 | ||
| 570 | @@ -324,6 +324,11 @@ | ||
| 571 | "sms-max-ii-factor", | ||
| 572 | "A factor for tuning the upper bound that swing modulo scheduler uses for scheduling a loop", | ||
| 573 | 100, 0, 0) | ||
| 574 | +/* The minimum value of stage count that swing modulo scheduler will generate. */ | ||
| 575 | +DEFPARAM(PARAM_SMS_MIN_SC, | ||
| 576 | + "sms-min-sc", | ||
| 577 | + "The minimum value of stage count that swing modulo scheduler will generate.", | ||
| 578 | + 2, 1, 1) | ||
| 579 | DEFPARAM(PARAM_SMS_DFA_HISTORY, | ||
| 580 | "sms-dfa-history", | ||
| 581 | "The number of cycles the swing modulo scheduler considers when checking conflicts using DFA", | ||
| 582 | |||
