1 /* Swing Modulo Scheduling implementation. 2 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 3 Free Software Foundation, Inc. 4 Contributed by Ayal Zaks and Mustafa Hagog <zaks,mustafa@il.ibm.com> 5 6 This file is part of GCC. 7 8 GCC is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free 10 Software Foundation; either version 3, or (at your option) any later 11 version. 12 13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 14 WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with GCC; see the file COPYING3. If not see 20 <http://www.gnu.org/licenses/>. */ 21 22 23 #include "config.h" 24 #include "system.h" 25 #include "coretypes.h" 26 #include "tm.h" 27 #include "diagnostic-core.h" 28 #include "rtl.h" 29 #include "tm_p.h" 30 #include "hard-reg-set.h" 31 #include "regs.h" 32 #include "function.h" 33 #include "flags.h" 34 #include "insn-config.h" 35 #include "insn-attr.h" 36 #include "except.h" 37 #include "recog.h" 38 #include "sched-int.h" 39 #include "target.h" 40 #include "cfglayout.h" 41 #include "cfgloop.h" 42 #include "cfghooks.h" 43 #include "expr.h" 44 #include "params.h" 45 #include "gcov-io.h" 46 #include "ddg.h" 47 #include "timevar.h" 48 #include "tree-pass.h" 49 #include "dbgcnt.h" 50 #include "df.h" 51 52 #ifdef INSN_SCHEDULING 53 54 /* This file contains the implementation of the Swing Modulo Scheduler, 55 described in the following references: 56 [1] J. Llosa, A. Gonzalez, E. Ayguade, M. Valero., and J. Eckhardt. 57 Lifetime--sensitive modulo scheduling in a production environment. 58 IEEE Trans. on Comps., 50(3), March 2001 59 [2] J. Llosa, A. Gonzalez, E. Ayguade, and M. Valero. 60 Swing Modulo Scheduling: A Lifetime Sensitive Approach. 61 PACT '96 , pages 80-87, October 1996 (Boston - Massachusetts - USA). 62 63 The basic structure is: 64 1. Build a data-dependence graph (DDG) for each loop. 65 2. Use the DDG to order the insns of a loop (not in topological order 66 necessarily, but rather) trying to place each insn after all its 67 predecessors _or_ after all its successors. 68 3. Compute MII: a lower bound on the number of cycles to schedule the loop. 69 4. Use the ordering to perform list-scheduling of the loop: 70 1. Set II = MII. We will try to schedule the loop within II cycles. 71 2. Try to schedule the insns one by one according to the ordering. 72 For each insn compute an interval of cycles by considering already- 73 scheduled preds and succs (and associated latencies); try to place 74 the insn in the cycles of this window checking for potential 75 resource conflicts (using the DFA interface). 76 Note: this is different from the cycle-scheduling of schedule_insns; 77 here the insns are not scheduled monotonically top-down (nor bottom- 78 up). 79 3. If failed in scheduling all insns - bump II++ and try again, unless 80 II reaches an upper bound MaxII, in which case report failure. 81 5. If we succeeded in scheduling the loop within II cycles, we now 82 generate prolog and epilog, decrease the counter of the loop, and 83 perform modulo variable expansion for live ranges that span more than 84 II cycles (i.e. use register copies to prevent a def from overwriting 85 itself before reaching the use). 86 87 SMS works with countable loops (1) whose control part can be easily 88 decoupled from the rest of the loop and (2) whose loop count can 89 be easily adjusted. This is because we peel a constant number of 90 iterations into a prologue and epilogue for which we want to avoid 91 emitting the control part, and a kernel which is to iterate that 92 constant number of iterations less than the original loop. So the 93 control part should be a set of insns clearly identified and having 94 its own iv, not otherwise used in the loop (at-least for now), which 95 initializes a register before the loop to the number of iterations. 96 Currently SMS relies on the do-loop pattern to recognize such loops, 97 where (1) the control part comprises of all insns defining and/or 98 using a certain 'count' register and (2) the loop count can be 99 adjusted by modifying this register prior to the loop. 100 TODO: Rely on cfgloop analysis instead. */ 101 102 /* This page defines partial-schedule structures and functions for 103 modulo scheduling. */ 104 105 typedef struct partial_schedule *partial_schedule_ptr; 106 typedef struct ps_insn *ps_insn_ptr; 107 108 /* The minimum (absolute) cycle that a node of ps was scheduled in. */ 109 #define PS_MIN_CYCLE(ps) (((partial_schedule_ptr)(ps))->min_cycle) 110 111 /* The maximum (absolute) cycle that a node of ps was scheduled in. */ 112 #define PS_MAX_CYCLE(ps) (((partial_schedule_ptr)(ps))->max_cycle) 113 114 /* Perform signed modulo, always returning a non-negative value. */ 115 #define SMODULO(x,y) ((x) % (y) < 0 ? ((x) % (y) + (y)) : (x) % (y)) 116 117 /* The number of different iterations the nodes in ps span, assuming 118 the stage boundaries are placed efficiently. */ 119 #define CALC_STAGE_COUNT(max_cycle,min_cycle,ii) ((max_cycle - min_cycle \ 120 + 1 + ii - 1) / ii) 121 /* The stage count of ps. */ 122 #define PS_STAGE_COUNT(ps) (((partial_schedule_ptr)(ps))->stage_count) 123 124 /* A single instruction in the partial schedule. */ 125 struct ps_insn 126 { 127 /* Identifies the instruction to be scheduled. Values smaller than 128 the ddg's num_nodes refer directly to ddg nodes. A value of 129 X - num_nodes refers to register move X. */ 130 int id; 131 132 /* The (absolute) cycle in which the PS instruction is scheduled. 133 Same as SCHED_TIME (node). */ 134 int cycle; 135 136 /* The next/prev PS_INSN in the same row. */ 137 ps_insn_ptr next_in_row, 138 prev_in_row; 139 140 }; 141 142 /* Information about a register move that has been added to a partial 143 schedule. */ 144 struct ps_reg_move_info 145 { 146 /* The source of the move is defined by the ps_insn with id DEF. 147 The destination is used by the ps_insns with the ids in USES. */ 148 int def; 149 sbitmap uses; 150 151 /* The original form of USES' instructions used OLD_REG, but they 152 should now use NEW_REG. */ 153 rtx old_reg; 154 rtx new_reg; 155 156 /* The number of consecutive stages that the move occupies. */ 157 int num_consecutive_stages; 158 159 /* An instruction that sets NEW_REG to the correct value. The first 160 move associated with DEF will have an rhs of OLD_REG; later moves 161 use the result of the previous move. */ 162 rtx insn; 163 }; 164 165 typedef struct ps_reg_move_info ps_reg_move_info; 166 DEF_VEC_O (ps_reg_move_info); 167 DEF_VEC_ALLOC_O (ps_reg_move_info, heap); 168 169 /* Holds the partial schedule as an array of II rows. Each entry of the 170 array points to a linked list of PS_INSNs, which represents the 171 instructions that are scheduled for that row. */ 172 struct partial_schedule 173 { 174 int ii; /* Number of rows in the partial schedule. */ 175 int history; /* Threshold for conflict checking using DFA. */ 176 177 /* rows[i] points to linked list of insns scheduled in row i (0<=i<ii). */ 178 ps_insn_ptr *rows; 179 180 /* All the moves added for this partial schedule. Index X has 181 a ps_insn id of X + g->num_nodes. */ 182 VEC (ps_reg_move_info, heap) *reg_moves; 183 184 /* rows_length[i] holds the number of instructions in the row. 185 It is used only (as an optimization) to back off quickly from 186 trying to schedule a node in a full row; that is, to avoid running 187 through futile DFA state transitions. */ 188 int *rows_length; 189 190 /* The earliest absolute cycle of an insn in the partial schedule. */ 191 int min_cycle; 192 193 /* The latest absolute cycle of an insn in the partial schedule. */ 194 int max_cycle; 195 196 ddg_ptr g; /* The DDG of the insns in the partial schedule. */ 197 198 int stage_count; /* The stage count of the partial schedule. */ 199 }; 200 201 202 static partial_schedule_ptr create_partial_schedule (int ii, ddg_ptr, int history); 203 static void free_partial_schedule (partial_schedule_ptr); 204 static void reset_partial_schedule (partial_schedule_ptr, int new_ii); 205 void print_partial_schedule (partial_schedule_ptr, FILE *); 206 static void verify_partial_schedule (partial_schedule_ptr, sbitmap); 207 static ps_insn_ptr ps_add_node_check_conflicts (partial_schedule_ptr, 208 int, int, sbitmap, sbitmap); 209 static void rotate_partial_schedule (partial_schedule_ptr, int); 210 void set_row_column_for_ps (partial_schedule_ptr); 211 static void ps_insert_empty_row (partial_schedule_ptr, int, sbitmap); 212 static int compute_split_row (sbitmap, int, int, int, ddg_node_ptr); 213 214 215 /* This page defines constants and structures for the modulo scheduling 216 driver. */ 217 218 static int sms_order_nodes (ddg_ptr, int, int *, int *); 219 static void set_node_sched_params (ddg_ptr); 220 static partial_schedule_ptr sms_schedule_by_order (ddg_ptr, int, int, int *); 221 static void permute_partial_schedule (partial_schedule_ptr, rtx); 222 static void generate_prolog_epilog (partial_schedule_ptr, struct loop *, 223 rtx, rtx); 224 static int calculate_stage_count (partial_schedule_ptr, int); 225 static void calculate_must_precede_follow (ddg_node_ptr, int, int, 226 int, int, sbitmap, sbitmap, sbitmap); 227 static int get_sched_window (partial_schedule_ptr, ddg_node_ptr, 228 sbitmap, int, int *, int *, int *); 229 static bool try_scheduling_node_in_cycle (partial_schedule_ptr, int, int, 230 sbitmap, int *, sbitmap, sbitmap); 231 static void remove_node_from_ps (partial_schedule_ptr, ps_insn_ptr); 232 233 #define NODE_ASAP(node) ((node)->aux.count) 234 235 #define SCHED_PARAMS(x) VEC_index (node_sched_params, node_sched_param_vec, x) 236 #define SCHED_TIME(x) (SCHED_PARAMS (x)->time) 237 #define SCHED_ROW(x) (SCHED_PARAMS (x)->row) 238 #define SCHED_STAGE(x) (SCHED_PARAMS (x)->stage) 239 #define SCHED_COLUMN(x) (SCHED_PARAMS (x)->column) 240 241 /* The scheduling parameters held for each node. */ 242 typedef struct node_sched_params 243 { 244 int time; /* The absolute scheduling cycle. */ 245 246 int row; /* Holds time % ii. */ 247 int stage; /* Holds time / ii. */ 248 249 /* The column of a node inside the ps. If nodes u, v are on the same row, 250 u will precede v if column (u) < column (v). */ 251 int column; 252 } *node_sched_params_ptr; 253 254 typedef struct node_sched_params node_sched_params; 255 DEF_VEC_O (node_sched_params); 256 DEF_VEC_ALLOC_O (node_sched_params, heap); 257 258 /* The following three functions are copied from the current scheduler 259 code in order to use sched_analyze() for computing the dependencies. 260 They are used when initializing the sched_info structure. */ 261 static const char * 262 sms_print_insn (const_rtx insn, int aligned ATTRIBUTE_UNUSED) 263 { 264 static char tmp[80]; 265 266 sprintf (tmp, "i%4d", INSN_UID (insn)); 267 return tmp; 268 } 269 270 static void 271 compute_jump_reg_dependencies (rtx insn ATTRIBUTE_UNUSED, 272 regset used ATTRIBUTE_UNUSED) 273 { 274 } 275 276 static struct common_sched_info_def sms_common_sched_info; 277 278 static struct sched_deps_info_def sms_sched_deps_info = 279 { 280 compute_jump_reg_dependencies, 281 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 282 NULL, 283 0, 0, 0 284 }; 285 286 static struct haifa_sched_info sms_sched_info = 287 { 288 NULL, 289 NULL, 290 NULL, 291 NULL, 292 NULL, 293 sms_print_insn, 294 NULL, 295 NULL, /* insn_finishes_block_p */ 296 NULL, NULL, 297 NULL, NULL, 298 0, 0, 299 300 NULL, NULL, NULL, NULL, 301 NULL, NULL, 302 0 303 }; 304 305 /* Partial schedule instruction ID in PS is a register move. Return 306 information about it. */ 307 static struct ps_reg_move_info * 308 ps_reg_move (partial_schedule_ptr ps, int id) 309 { 310 gcc_checking_assert (id >= ps->g->num_nodes); 311 return VEC_index (ps_reg_move_info, ps->reg_moves, id - ps->g->num_nodes); 312 } 313 314 /* Return the rtl instruction that is being scheduled by partial schedule 315 instruction ID, which belongs to schedule PS. */ 316 static rtx 317 ps_rtl_insn (partial_schedule_ptr ps, int id) 318 { 319 if (id < ps->g->num_nodes) 320 return ps->g->nodes[id].insn; 321 else 322 return ps_reg_move (ps, id)->insn; 323 } 324 325 /* Partial schedule instruction ID, which belongs to PS, occured in 326 the original (unscheduled) loop. Return the first instruction 327 in the loop that was associated with ps_rtl_insn (PS, ID). 328 If the instruction had some notes before it, this is the first 329 of those notes. */ 330 static rtx 331 ps_first_note (partial_schedule_ptr ps, int id) 332 { 333 gcc_assert (id < ps->g->num_nodes); 334 return ps->g->nodes[id].first_note; 335 } 336 337 /* Return the number of consecutive stages that are occupied by 338 partial schedule instruction ID in PS. */ 339 static int 340 ps_num_consecutive_stages (partial_schedule_ptr ps, int id) 341 { 342 if (id < ps->g->num_nodes) 343 return 1; 344 else 345 return ps_reg_move (ps, id)->num_consecutive_stages; 346 } 347 348 /* Given HEAD and TAIL which are the first and last insns in a loop; 349 return the register which controls the loop. Return zero if it has 350 more than one occurrence in the loop besides the control part or the 351 do-loop pattern is not of the form we expect. */ 352 static rtx 353 doloop_register_get (rtx head ATTRIBUTE_UNUSED, rtx tail ATTRIBUTE_UNUSED) 354 { 355 #ifdef HAVE_doloop_end 356 rtx reg, condition, insn, first_insn_not_to_check; 357 358 if (!JUMP_P (tail)) 359 return NULL_RTX; 360 361 /* TODO: Free SMS's dependence on doloop_condition_get. */ 362 condition = doloop_condition_get (tail); 363 if (! condition) 364 return NULL_RTX; 365 366 if (REG_P (XEXP (condition, 0))) 367 reg = XEXP (condition, 0); 368 else if (GET_CODE (XEXP (condition, 0)) == PLUS 369 && REG_P (XEXP (XEXP (condition, 0), 0))) 370 reg = XEXP (XEXP (condition, 0), 0); 371 else 372 gcc_unreachable (); 373 374 /* Check that the COUNT_REG has no other occurrences in the loop 375 until the decrement. We assume the control part consists of 376 either a single (parallel) branch-on-count or a (non-parallel) 377 branch immediately preceded by a single (decrement) insn. */ 378 first_insn_not_to_check = (GET_CODE (PATTERN (tail)) == PARALLEL ? tail 379 : prev_nondebug_insn (tail)); 380 381 for (insn = head; insn != first_insn_not_to_check; insn = NEXT_INSN (insn)) 382 if (!DEBUG_INSN_P (insn) && reg_mentioned_p (reg, insn)) 383 { 384 if (dump_file) 385 { 386 fprintf (dump_file, "SMS count_reg found "); 387 print_rtl_single (dump_file, reg); 388 fprintf (dump_file, " outside control in insn:\n"); 389 print_rtl_single (dump_file, insn); 390 } 391 392 return NULL_RTX; 393 } 394 395 return reg; 396 #else 397 return NULL_RTX; 398 #endif 399 } 400 401 /* Check if COUNT_REG is set to a constant in the PRE_HEADER block, so 402 that the number of iterations is a compile-time constant. If so, 403 return the rtx that sets COUNT_REG to a constant, and set COUNT to 404 this constant. Otherwise return 0. */ 405 static rtx 406 const_iteration_count (rtx count_reg, basic_block pre_header, 407 HOST_WIDEST_INT * count) 408 { 409 rtx insn; 410 rtx head, tail; 411 412 if (! pre_header) 413 return NULL_RTX; 414 415 get_ebb_head_tail (pre_header, pre_header, &head, &tail); 416 417 for (insn = tail; insn != PREV_INSN (head); insn = PREV_INSN (insn)) 418 if (NONDEBUG_INSN_P (insn) && single_set (insn) && 419 rtx_equal_p (count_reg, SET_DEST (single_set (insn)))) 420 { 421 rtx pat = single_set (insn); 422 423 if (CONST_INT_P (SET_SRC (pat))) 424 { 425 *count = INTVAL (SET_SRC (pat)); 426 return insn; 427 } 428 429 return NULL_RTX; 430 } 431 432 return NULL_RTX; 433 } 434 435 /* A very simple resource-based lower bound on the initiation interval. 436 ??? Improve the accuracy of this bound by considering the 437 utilization of various units. */ 438 static int 439 res_MII (ddg_ptr g) 440 { 441 if (targetm.sched.sms_res_mii) 442 return targetm.sched.sms_res_mii (g); 443 444 return ((g->num_nodes - g->num_debug) / issue_rate); 445 } 446 447 448 /* A vector that contains the sched data for each ps_insn. */ 449 static VEC (node_sched_params, heap) *node_sched_param_vec; 450 451 /* Allocate sched_params for each node and initialize it. */ 452 static void 453 set_node_sched_params (ddg_ptr g) 454 { 455 VEC_truncate (node_sched_params, node_sched_param_vec, 0); 456 VEC_safe_grow_cleared (node_sched_params, heap, 457 node_sched_param_vec, g->num_nodes); 458 } 459 460 /* Make sure that node_sched_param_vec has an entry for every move in PS. */ 461 static void 462 extend_node_sched_params (partial_schedule_ptr ps) 463 { 464 VEC_safe_grow_cleared (node_sched_params, heap, node_sched_param_vec, 465 ps->g->num_nodes + VEC_length (ps_reg_move_info, 466 ps->reg_moves)); 467 } 468 469 /* Update the sched_params (time, row and stage) for node U using the II, 470 the CYCLE of U and MIN_CYCLE. 471 We're not simply taking the following 472 SCHED_STAGE (u) = CALC_STAGE_COUNT (SCHED_TIME (u), min_cycle, ii); 473 because the stages may not be aligned on cycle 0. */ 474 static void 475 update_node_sched_params (int u, int ii, int cycle, int min_cycle) 476 { 477 int sc_until_cycle_zero; 478 int stage; 479 480 SCHED_TIME (u) = cycle; 481 SCHED_ROW (u) = SMODULO (cycle, ii); 482 483 /* The calculation of stage count is done adding the number 484 of stages before cycle zero and after cycle zero. */ 485 sc_until_cycle_zero = CALC_STAGE_COUNT (-1, min_cycle, ii); 486 487 if (SCHED_TIME (u) < 0) 488 { 489 stage = CALC_STAGE_COUNT (-1, SCHED_TIME (u), ii); 490 SCHED_STAGE (u) = sc_until_cycle_zero - stage; 491 } 492 else 493 { 494 stage = CALC_STAGE_COUNT (SCHED_TIME (u), 0, ii); 495 SCHED_STAGE (u) = sc_until_cycle_zero + stage - 1; 496 } 497 } 498 499 static void 500 print_node_sched_params (FILE *file, int num_nodes, partial_schedule_ptr ps) 501 { 502 int i; 503 504 if (! file) 505 return; 506 for (i = 0; i < num_nodes; i++) 507 { 508 node_sched_params_ptr nsp = SCHED_PARAMS (i); 509 510 fprintf (file, "Node = %d; INSN = %d\n", i, 511 INSN_UID (ps_rtl_insn (ps, i))); 512 fprintf (file, " asap = %d:\n", NODE_ASAP (&ps->g->nodes[i])); 513 fprintf (file, " time = %d:\n", nsp->time); 514 fprintf (file, " stage = %d:\n", nsp->stage); 515 } 516 } 517 518 /* Set SCHED_COLUMN for each instruction in row ROW of PS. */ 519 static void 520 set_columns_for_row (partial_schedule_ptr ps, int row) 521 { 522 ps_insn_ptr cur_insn; 523 int column; 524 525 column = 0; 526 for (cur_insn = ps->rows[row]; cur_insn; cur_insn = cur_insn->next_in_row) 527 SCHED_COLUMN (cur_insn->id) = column++; 528 } 529 530 /* Set SCHED_COLUMN for each instruction in PS. */ 531 static void 532 set_columns_for_ps (partial_schedule_ptr ps) 533 { 534 int row; 535 536 for (row = 0; row < ps->ii; row++) 537 set_columns_for_row (ps, row); 538 } 539 540 /* Try to schedule the move with ps_insn identifier I_REG_MOVE in PS. 541 Its single predecessor has already been scheduled, as has its 542 ddg node successors. (The move may have also another move as its 543 successor, in which case that successor will be scheduled later.) 544 545 The move is part of a chain that satisfies register dependencies 546 between a producing ddg node and various consuming ddg nodes. 547 If some of these dependencies have a distance of 1 (meaning that 548 the use is upward-exposed) then DISTANCE1_USES is nonnull and 549 contains the set of uses with distance-1 dependencies. 550 DISTANCE1_USES is null otherwise. 551 552 MUST_FOLLOW is a scratch bitmap that is big enough to hold 553 all current ps_insn ids. 554 555 Return true on success. */ 556 static bool 557 schedule_reg_move (partial_schedule_ptr ps, int i_reg_move, 558 sbitmap distance1_uses, sbitmap must_follow) 559 { 560 unsigned int u; 561 int this_time, this_distance, this_start, this_end, this_latency; 562 int start, end, c, ii; 563 sbitmap_iterator sbi; 564 ps_reg_move_info *move; 565 rtx this_insn; 566 ps_insn_ptr psi; 567 568 move = ps_reg_move (ps, i_reg_move); 569 ii = ps->ii; 570 if (dump_file) 571 { 572 fprintf (dump_file, "Scheduling register move INSN %d; ii = %d" 573 ", min cycle = %d\n\n", INSN_UID (move->insn), ii, 574 PS_MIN_CYCLE (ps)); 575 print_rtl_single (dump_file, move->insn); 576 fprintf (dump_file, "\n%11s %11s %5s\n", "start", "end", "time"); 577 fprintf (dump_file, "=========== =========== =====\n"); 578 } 579 580 start = INT_MIN; 581 end = INT_MAX; 582 583 /* For dependencies of distance 1 between a producer ddg node A 584 and consumer ddg node B, we have a chain of dependencies: 585 586 A --(T,L1,1)--> M1 --(T,L2,0)--> M2 ... --(T,Ln,0)--> B 587 588 where Mi is the ith move. For dependencies of distance 0 between 589 a producer ddg node A and consumer ddg node C, we have a chain of 590 dependencies: 591 592 A --(T,L1',0)--> M1' --(T,L2',0)--> M2' ... --(T,Ln',0)--> C 593 594 where Mi' occupies the same position as Mi but occurs a stage later. 595 We can only schedule each move once, so if we have both types of 596 chain, we model the second as: 597 598 A --(T,L1',1)--> M1 --(T,L2',0)--> M2 ... --(T,Ln',-1)--> C 599 600 First handle the dependencies between the previously-scheduled 601 predecessor and the move. */ 602 this_insn = ps_rtl_insn (ps, move->def); 603 this_latency = insn_latency (this_insn, move->insn); 604 this_distance = distance1_uses && move->def < ps->g->num_nodes ? 1 : 0; 605 this_time = SCHED_TIME (move->def) - this_distance * ii; 606 this_start = this_time + this_latency; 607 this_end = this_time + ii; 608 if (dump_file) 609 fprintf (dump_file, "%11d %11d %5d %d --(T,%d,%d)--> %d\n", 610 this_start, this_end, SCHED_TIME (move->def), 611 INSN_UID (this_insn), this_latency, this_distance, 612 INSN_UID (move->insn)); 613 614 if (start < this_start) 615 start = this_start; 616 if (end > this_end) 617 end = this_end; 618 619 /* Handle the dependencies between the move and previously-scheduled 620 successors. */ 621 EXECUTE_IF_SET_IN_SBITMAP (move->uses, 0, u, sbi) 622 { 623 this_insn = ps_rtl_insn (ps, u); 624 this_latency = insn_latency (move->insn, this_insn); 625 if (distance1_uses && !TEST_BIT (distance1_uses, u)) 626 this_distance = -1; 627 else 628 this_distance = 0; 629 this_time = SCHED_TIME (u) + this_distance * ii; 630 this_start = this_time - ii; 631 this_end = this_time - this_latency; 632 if (dump_file) 633 fprintf (dump_file, "%11d %11d %5d %d --(T,%d,%d)--> %d\n", 634 this_start, this_end, SCHED_TIME (u), INSN_UID (move->insn), 635 this_latency, this_distance, INSN_UID (this_insn)); 636 637 if (start < this_start) 638 start = this_start; 639 if (end > this_end) 640 end = this_end; 641 } 642 643 if (dump_file) 644 { 645 fprintf (dump_file, "----------- ----------- -----\n"); 646 fprintf (dump_file, "%11d %11d %5s %s\n", start, end, "", "(max, min)"); 647 } 648 649 sbitmap_zero (must_follow); 650 SET_BIT (must_follow, move->def); 651 652 start = MAX (start, end - (ii - 1)); 653 for (c = end; c >= start; c--) 654 { 655 psi = ps_add_node_check_conflicts (ps, i_reg_move, c, 656 move->uses, must_follow); 657 if (psi) 658 { 659 update_node_sched_params (i_reg_move, ii, c, PS_MIN_CYCLE (ps)); 660 if (dump_file) 661 fprintf (dump_file, "\nScheduled register move INSN %d at" 662 " time %d, row %d\n\n", INSN_UID (move->insn), c, 663 SCHED_ROW (i_reg_move)); 664 return true; 665 } 666 } 667 668 if (dump_file) 669 fprintf (dump_file, "\nNo available slot\n\n"); 670 671 return false; 672 } 673 674 /* 675 Breaking intra-loop register anti-dependences: 676 Each intra-loop register anti-dependence implies a cross-iteration true 677 dependence of distance 1. Therefore, we can remove such false dependencies 678 and figure out if the partial schedule broke them by checking if (for a 679 true-dependence of distance 1): SCHED_TIME (def) < SCHED_TIME (use) and 680 if so generate a register move. The number of such moves is equal to: 681 SCHED_TIME (use) - SCHED_TIME (def) { 0 broken 682 nreg_moves = ----------------------------------- + 1 - { dependence. 683 ii { 1 if not. 684 */ 685 static bool 686 schedule_reg_moves (partial_schedule_ptr ps) 687 { 688 ddg_ptr g = ps->g; 689 int ii = ps->ii; 690 int i; 691 692 for (i = 0; i < g->num_nodes; i++) 693 { 694 ddg_node_ptr u = &g->nodes[i]; 695 ddg_edge_ptr e; 696 int nreg_moves = 0, i_reg_move; 697 rtx prev_reg, old_reg; 698 int first_move; 699 int distances[2]; 700 sbitmap must_follow; 701 sbitmap distance1_uses; 702 rtx set = single_set (u->insn); 703 704 /* Skip instructions that do not set a register. */ 705 if ((set && !REG_P (SET_DEST (set)))) 706 continue; 707 708 /* Compute the number of reg_moves needed for u, by looking at life 709 ranges started at u (excluding self-loops). */ 710 distances[0] = distances[1] = false; 711 for (e = u->out; e; e = e->next_out) 712 if (e->type == TRUE_DEP && e->dest != e->src) 713 { 714 int nreg_moves4e = (SCHED_TIME (e->dest->cuid) 715 - SCHED_TIME (e->src->cuid)) / ii; 716 717 if (e->distance == 1) 718 nreg_moves4e = (SCHED_TIME (e->dest->cuid) 719 - SCHED_TIME (e->src->cuid) + ii) / ii; 720 721 /* If dest precedes src in the schedule of the kernel, then dest 722 will read before src writes and we can save one reg_copy. */ 723 if (SCHED_ROW (e->dest->cuid) == SCHED_ROW (e->src->cuid) 724 && SCHED_COLUMN (e->dest->cuid) < SCHED_COLUMN (e->src->cuid)) 725 nreg_moves4e--; 726 727 if (nreg_moves4e >= 1) 728 { 729 /* !single_set instructions are not supported yet and 730 thus we do not except to encounter them in the loop 731 except from the doloop part. For the latter case 732 we assume no regmoves are generated as the doloop 733 instructions are tied to the branch with an edge. */ 734 gcc_assert (set); 735 /* If the instruction contains auto-inc register then 736 validate that the regmov is being generated for the 737 target regsiter rather then the inc'ed register. */ 738 gcc_assert (!autoinc_var_is_used_p (u->insn, e->dest->insn)); 739 } 740 741 if (nreg_moves4e) 742 { 743 gcc_assert (e->distance < 2); 744 distances[e->distance] = true; 745 } 746 nreg_moves = MAX (nreg_moves, nreg_moves4e); 747 } 748 749 if (nreg_moves == 0) 750 continue; 751 752 /* Create NREG_MOVES register moves. */ 753 first_move = VEC_length (ps_reg_move_info, ps->reg_moves); 754 VEC_safe_grow_cleared (ps_reg_move_info, heap, ps->reg_moves, 755 first_move + nreg_moves); 756 extend_node_sched_params (ps); 757 758 /* Record the moves associated with this node. */ 759 first_move += ps->g->num_nodes; 760 761 /* Generate each move. */ 762 old_reg = prev_reg = SET_DEST (single_set (u->insn)); 763 for (i_reg_move = 0; i_reg_move < nreg_moves; i_reg_move++) 764 { 765 ps_reg_move_info *move = ps_reg_move (ps, first_move + i_reg_move); 766 767 move->def = i_reg_move > 0 ? first_move + i_reg_move - 1 : i; 768 move->uses = sbitmap_alloc (first_move + nreg_moves); 769 move->old_reg = old_reg; 770 move->new_reg = gen_reg_rtx (GET_MODE (prev_reg)); 771 move->num_consecutive_stages = distances[0] && distances[1] ? 2 : 1; 772 move->insn = gen_move_insn (move->new_reg, copy_rtx (prev_reg)); 773 sbitmap_zero (move->uses); 774 775 prev_reg = move->new_reg; 776 } 777 778 distance1_uses = distances[1] ? sbitmap_alloc (g->num_nodes) : NULL; 779 780 /* Every use of the register defined by node may require a different 781 copy of this register, depending on the time the use is scheduled. 782 Record which uses require which move results. */ 783 for (e = u->out; e; e = e->next_out) 784 if (e->type == TRUE_DEP && e->dest != e->src) 785 { 786 int dest_copy = (SCHED_TIME (e->dest->cuid) 787 - SCHED_TIME (e->src->cuid)) / ii; 788 789 if (e->distance == 1) 790 dest_copy = (SCHED_TIME (e->dest->cuid) 791 - SCHED_TIME (e->src->cuid) + ii) / ii; 792 793 if (SCHED_ROW (e->dest->cuid) == SCHED_ROW (e->src->cuid) 794 && SCHED_COLUMN (e->dest->cuid) < SCHED_COLUMN (e->src->cuid)) 795 dest_copy--; 796 797 if (dest_copy) 798 { 799 ps_reg_move_info *move; 800 801 move = ps_reg_move (ps, first_move + dest_copy - 1); 802 SET_BIT (move->uses, e->dest->cuid); 803 if (e->distance == 1) 804 SET_BIT (distance1_uses, e->dest->cuid); 805 } 806 } 807 808 must_follow = sbitmap_alloc (first_move + nreg_moves); 809 for (i_reg_move = 0; i_reg_move < nreg_moves; i_reg_move++) 810 if (!schedule_reg_move (ps, first_move + i_reg_move, 811 distance1_uses, must_follow)) 812 break; 813 sbitmap_free (must_follow); 814 if (distance1_uses) 815 sbitmap_free (distance1_uses); 816 if (i_reg_move < nreg_moves) 817 return false; 818 } 819 return true; 820 } 821 822 /* Emit the moves associatied with PS. Apply the substitutions 823 associated with them. */ 824 static void 825 apply_reg_moves (partial_schedule_ptr ps) 826 { 827 ps_reg_move_info *move; 828 int i; 829 830 FOR_EACH_VEC_ELT (ps_reg_move_info, ps->reg_moves, i, move) 831 { 832 unsigned int i_use; 833 sbitmap_iterator sbi; 834 835 EXECUTE_IF_SET_IN_SBITMAP (move->uses, 0, i_use, sbi) 836 { 837 replace_rtx (ps->g->nodes[i_use].insn, move->old_reg, move->new_reg); 838 df_insn_rescan (ps->g->nodes[i_use].insn); 839 } 840 } 841 } 842 843 /* Bump the SCHED_TIMEs of all nodes by AMOUNT. Set the values of 844 SCHED_ROW and SCHED_STAGE. Instruction scheduled on cycle AMOUNT 845 will move to cycle zero. */ 846 static void 847 reset_sched_times (partial_schedule_ptr ps, int amount) 848 { 849 int row; 850 int ii = ps->ii; 851 ps_insn_ptr crr_insn; 852 853 for (row = 0; row < ii; row++) 854 for (crr_insn = ps->rows[row]; crr_insn; crr_insn = crr_insn->next_in_row) 855 { 856 int u = crr_insn->id; 857 int normalized_time = SCHED_TIME (u) - amount; 858 int new_min_cycle = PS_MIN_CYCLE (ps) - amount; 859 860 if (dump_file) 861 { 862 /* Print the scheduling times after the rotation. */ 863 rtx insn = ps_rtl_insn (ps, u); 864 865 fprintf (dump_file, "crr_insn->node=%d (insn id %d), " 866 "crr_insn->cycle=%d, min_cycle=%d", u, 867 INSN_UID (insn), normalized_time, new_min_cycle); 868 if (JUMP_P (insn)) 869 fprintf (dump_file, " (branch)"); 870 fprintf (dump_file, "\n"); 871 } 872 873 gcc_assert (SCHED_TIME (u) >= ps->min_cycle); 874 gcc_assert (SCHED_TIME (u) <= ps->max_cycle); 875 876 crr_insn->cycle = normalized_time; 877 update_node_sched_params (u, ii, normalized_time, new_min_cycle); 878 } 879 } 880 881 /* Permute the insns according to their order in PS, from row 0 to 882 row ii-1, and position them right before LAST. This schedules 883 the insns of the loop kernel. */ 884 static void 885 permute_partial_schedule (partial_schedule_ptr ps, rtx last) 886 { 887 int ii = ps->ii; 888 int row; 889 ps_insn_ptr ps_ij; 890 891 for (row = 0; row < ii ; row++) 892 for (ps_ij = ps->rows[row]; ps_ij; ps_ij = ps_ij->next_in_row) 893 { 894 rtx insn = ps_rtl_insn (ps, ps_ij->id); 895 896 if (PREV_INSN (last) != insn) 897 { 898 if (ps_ij->id < ps->g->num_nodes) 899 reorder_insns_nobb (ps_first_note (ps, ps_ij->id), insn, 900 PREV_INSN (last)); 901 else 902 add_insn_before (insn, last, NULL); 903 } 904 } 905 } 906 907 /* Set bitmaps TMP_FOLLOW and TMP_PRECEDE to MUST_FOLLOW and MUST_PRECEDE 908 respectively only if cycle C falls on the border of the scheduling 909 window boundaries marked by START and END cycles. STEP is the 910 direction of the window. */ 911 static inline void 912 set_must_precede_follow (sbitmap *tmp_follow, sbitmap must_follow, 913 sbitmap *tmp_precede, sbitmap must_precede, int c, 914 int start, int end, int step) 915 { 916 *tmp_precede = NULL; 917 *tmp_follow = NULL; 918 919 if (c == start) 920 { 921 if (step == 1) 922 *tmp_precede = must_precede; 923 else /* step == -1. */ 924 *tmp_follow = must_follow; 925 } 926 if (c == end - step) 927 { 928 if (step == 1) 929 *tmp_follow = must_follow; 930 else /* step == -1. */ 931 *tmp_precede = must_precede; 932 } 933 934 } 935 936 /* Return True if the branch can be moved to row ii-1 while 937 normalizing the partial schedule PS to start from cycle zero and thus 938 optimize the SC. Otherwise return False. */ 939 static bool 940 optimize_sc (partial_schedule_ptr ps, ddg_ptr g) 941 { 942 int amount = PS_MIN_CYCLE (ps); 943 sbitmap sched_nodes = sbitmap_alloc (g->num_nodes); 944 int start, end, step; 945 int ii = ps->ii; 946 bool ok = false; 947 int stage_count, stage_count_curr; 948 949 /* Compare the SC after normalization and SC after bringing the branch 950 to row ii-1. If they are equal just bail out. */ 951 stage_count = calculate_stage_count (ps, amount); 952 stage_count_curr = 953 calculate_stage_count (ps, SCHED_TIME (g->closing_branch->cuid) - (ii - 1)); 954 955 if (stage_count == stage_count_curr) 956 { 957 if (dump_file) 958 fprintf (dump_file, "SMS SC already optimized.\n"); 959 960 ok = false; 961 goto clear; 962 } 963 964 if (dump_file) 965 { 966 fprintf (dump_file, "SMS Trying to optimize branch location\n"); 967 fprintf (dump_file, "SMS partial schedule before trial:\n"); 968 print_partial_schedule (ps, dump_file); 969 } 970 971 /* First, normalize the partial scheduling. */ 972 reset_sched_times (ps, amount); 973 rotate_partial_schedule (ps, amount); 974 if (dump_file) 975 { 976 fprintf (dump_file, 977 "SMS partial schedule after normalization (ii, %d, SC %d):\n", 978 ii, stage_count); 979 print_partial_schedule (ps, dump_file); 980 } 981 982 if (SMODULO (SCHED_TIME (g->closing_branch->cuid), ii) == ii - 1) 983 { 984 ok = true; 985 goto clear; 986 } 987 988 sbitmap_ones (sched_nodes); 989 990 /* Calculate the new placement of the branch. It should be in row 991 ii-1 and fall into it's scheduling window. */ 992 if (get_sched_window (ps, g->closing_branch, sched_nodes, ii, &start, 993 &step, &end) == 0) 994 { 995 bool success; 996 ps_insn_ptr next_ps_i; 997 int branch_cycle = SCHED_TIME (g->closing_branch->cuid); 998 int row = SMODULO (branch_cycle, ps->ii); 999 int num_splits = 0; 1000 sbitmap must_precede, must_follow, tmp_precede, tmp_follow; 1001 int c; 1002 1003 if (dump_file) 1004 fprintf (dump_file, "\nTrying to schedule node %d " 1005 "INSN = %d in (%d .. %d) step %d\n", 1006 g->closing_branch->cuid, 1007 (INSN_UID (g->closing_branch->insn)), start, end, step); 1008 1009 gcc_assert ((step > 0 && start < end) || (step < 0 && start > end)); 1010 if (step == 1) 1011 { 1012 c = start + ii - SMODULO (start, ii) - 1; 1013 gcc_assert (c >= start); 1014 if (c >= end) 1015 { 1016 ok = false; 1017 if (dump_file) 1018 fprintf (dump_file, 1019 "SMS failed to schedule branch at cycle: %d\n", c); 1020 goto clear; 1021 } 1022 } 1023 else 1024 { 1025 c = start - SMODULO (start, ii) - 1; 1026 gcc_assert (c <= start); 1027 1028 if (c <= end) 1029 { 1030 if (dump_file) 1031 fprintf (dump_file, 1032 "SMS failed to schedule branch at cycle: %d\n", c); 1033 ok = false; 1034 goto clear; 1035 } 1036 } 1037 1038 must_precede = sbitmap_alloc (g->num_nodes); 1039 must_follow = sbitmap_alloc (g->num_nodes); 1040 1041 /* Try to schedule the branch is it's new cycle. */ 1042 calculate_must_precede_follow (g->closing_branch, start, end, 1043 step, ii, sched_nodes, 1044 must_precede, must_follow); 1045 1046 set_must_precede_follow (&tmp_follow, must_follow, &tmp_precede, 1047 must_precede, c, start, end, step); 1048 1049 /* Find the element in the partial schedule related to the closing 1050 branch so we can remove it from it's current cycle. */ 1051 for (next_ps_i = ps->rows[row]; 1052 next_ps_i; next_ps_i = next_ps_i->next_in_row) 1053 if (next_ps_i->id == g->closing_branch->cuid) 1054 break; 1055 1056 remove_node_from_ps (ps, next_ps_i); 1057 success = 1058 try_scheduling_node_in_cycle (ps, g->closing_branch->cuid, c, 1059 sched_nodes, &num_splits, 1060 tmp_precede, tmp_follow); 1061 gcc_assert (num_splits == 0); 1062 if (!success) 1063 { 1064 if (dump_file) 1065 fprintf (dump_file, 1066 "SMS failed to schedule branch at cycle: %d, " 1067 "bringing it back to cycle %d\n", c, branch_cycle); 1068 1069 /* The branch was failed to be placed in row ii - 1. 1070 Put it back in it's original place in the partial 1071 schedualing. */ 1072 set_must_precede_follow (&tmp_follow, must_follow, &tmp_precede, 1073 must_precede, branch_cycle, start, end, 1074 step); 1075 success = 1076 try_scheduling_node_in_cycle (ps, g->closing_branch->cuid, 1077 branch_cycle, sched_nodes, 1078 &num_splits, tmp_precede, 1079 tmp_follow); 1080 gcc_assert (success && (num_splits == 0)); 1081 ok = false; 1082 } 1083 else 1084 { 1085 /* The branch is placed in row ii - 1. */ 1086 if (dump_file) 1087 fprintf (dump_file, 1088 "SMS success in moving branch to cycle %d\n", c); 1089 1090 update_node_sched_params (g->closing_branch->cuid, ii, c, 1091 PS_MIN_CYCLE (ps)); 1092 ok = true; 1093 } 1094 1095 free (must_precede); 1096 free (must_follow); 1097 } 1098 1099 clear: 1100 free (sched_nodes); 1101 return ok; 1102 } 1103 1104 static void 1105 duplicate_insns_of_cycles (partial_schedule_ptr ps, int from_stage, 1106 int to_stage, rtx count_reg) 1107 { 1108 int row; 1109 ps_insn_ptr ps_ij; 1110 1111 for (row = 0; row < ps->ii; row++) 1112 for (ps_ij = ps->rows[row]; ps_ij; ps_ij = ps_ij->next_in_row) 1113 { 1114 int u = ps_ij->id; 1115 int first_u, last_u; 1116 rtx u_insn; 1117 1118 /* Do not duplicate any insn which refers to count_reg as it 1119 belongs to the control part. 1120 The closing branch is scheduled as well and thus should 1121 be ignored. 1122 TODO: This should be done by analyzing the control part of 1123 the loop. */ 1124 u_insn = ps_rtl_insn (ps, u); 1125 if (reg_mentioned_p (count_reg, u_insn) 1126 || JUMP_P (u_insn)) 1127 continue; 1128 1129 first_u = SCHED_STAGE (u); 1130 last_u = first_u + ps_num_consecutive_stages (ps, u) - 1; 1131 if (from_stage <= last_u && to_stage >= first_u) 1132 { 1133 if (u < ps->g->num_nodes) 1134 duplicate_insn_chain (ps_first_note (ps, u), u_insn); 1135 else 1136 emit_insn (copy_rtx (PATTERN (u_insn))); 1137 } 1138 } 1139 } 1140 1141 1142 /* Generate the instructions (including reg_moves) for prolog & epilog. */ 1143 static void 1144 generate_prolog_epilog (partial_schedule_ptr ps, struct loop *loop, 1145 rtx count_reg, rtx count_init) 1146 { 1147 int i; 1148 int last_stage = PS_STAGE_COUNT (ps) - 1; 1149 edge e; 1150 1151 /* Generate the prolog, inserting its insns on the loop-entry edge. */ 1152 start_sequence (); 1153 1154 if (!count_init) 1155 { 1156 /* Generate instructions at the beginning of the prolog to 1157 adjust the loop count by STAGE_COUNT. If loop count is constant 1158 (count_init), this constant is adjusted by STAGE_COUNT in 1159 generate_prolog_epilog function. */ 1160 rtx sub_reg = NULL_RTX; 1161 1162 sub_reg = expand_simple_binop (GET_MODE (count_reg), MINUS, 1163 count_reg, GEN_INT (last_stage), 1164 count_reg, 1, OPTAB_DIRECT); 1165 gcc_assert (REG_P (sub_reg)); 1166 if (REGNO (sub_reg) != REGNO (count_reg)) 1167 emit_move_insn (count_reg, sub_reg); 1168 } 1169 1170 for (i = 0; i < last_stage; i++) 1171 duplicate_insns_of_cycles (ps, 0, i, count_reg); 1172 1173 /* Put the prolog on the entry edge. */ 1174 e = loop_preheader_edge (loop); 1175 split_edge_and_insert (e, get_insns ()); 1176 if (!flag_resched_modulo_sched) 1177 e->dest->flags |= BB_DISABLE_SCHEDULE; 1178 1179 end_sequence (); 1180 1181 /* Generate the epilog, inserting its insns on the loop-exit edge. */ 1182 start_sequence (); 1183 1184 for (i = 0; i < last_stage; i++) 1185 duplicate_insns_of_cycles (ps, i + 1, last_stage, count_reg); 1186 1187 /* Put the epilogue on the exit edge. */ 1188 gcc_assert (single_exit (loop)); 1189 e = single_exit (loop); 1190 split_edge_and_insert (e, get_insns ()); 1191 if (!flag_resched_modulo_sched) 1192 e->dest->flags |= BB_DISABLE_SCHEDULE; 1193 1194 end_sequence (); 1195 } 1196 1197 /* Mark LOOP as software pipelined so the later 1198 scheduling passes don't touch it. */ 1199 static void 1200 mark_loop_unsched (struct loop *loop) 1201 { 1202 unsigned i; 1203 basic_block *bbs = get_loop_body (loop); 1204 1205 for (i = 0; i < loop->num_nodes; i++) 1206 bbs[i]->flags |= BB_DISABLE_SCHEDULE; 1207 1208 free (bbs); 1209 } 1210 1211 /* Return true if all the BBs of the loop are empty except the 1212 loop header. */ 1213 static bool 1214 loop_single_full_bb_p (struct loop *loop) 1215 { 1216 unsigned i; 1217 basic_block *bbs = get_loop_body (loop); 1218 1219 for (i = 0; i < loop->num_nodes ; i++) 1220 { 1221 rtx head, tail; 1222 bool empty_bb = true; 1223 1224 if (bbs[i] == loop->header) 1225 continue; 1226 1227 /* Make sure that basic blocks other than the header 1228 have only notes labels or jumps. */ 1229 get_ebb_head_tail (bbs[i], bbs[i], &head, &tail); 1230 for (; head != NEXT_INSN (tail); head = NEXT_INSN (head)) 1231 { 1232 if (NOTE_P (head) || LABEL_P (head) 1233 || (INSN_P (head) && (DEBUG_INSN_P (head) || JUMP_P (head)))) 1234 continue; 1235 empty_bb = false; 1236 break; 1237 } 1238 1239 if (! empty_bb) 1240 { 1241 free (bbs); 1242 return false; 1243 } 1244 } 1245 free (bbs); 1246 return true; 1247 } 1248 1249 /* Dump file:line from INSN's location info to dump_file. */ 1250 1251 static void 1252 dump_insn_locator (rtx insn) 1253 { 1254 if (dump_file && INSN_LOCATOR (insn)) 1255 { 1256 const char *file = insn_file (insn); 1257 if (file) 1258 fprintf (dump_file, " %s:%i", file, insn_line (insn)); 1259 } 1260 } 1261 1262 /* A simple loop from SMS point of view; it is a loop that is composed of 1263 either a single basic block or two BBs - a header and a latch. */ 1264 #define SIMPLE_SMS_LOOP_P(loop) ((loop->num_nodes < 3 ) \ 1265 && (EDGE_COUNT (loop->latch->preds) == 1) \ 1266 && (EDGE_COUNT (loop->latch->succs) == 1)) 1267 1268 /* Return true if the loop is in its canonical form and false if not. 1269 i.e. SIMPLE_SMS_LOOP_P and have one preheader block, and single exit. */ 1270 static bool 1271 loop_canon_p (struct loop *loop) 1272 { 1273 1274 if (loop->inner || !loop_outer (loop)) 1275 { 1276 if (dump_file) 1277 fprintf (dump_file, "SMS loop inner or !loop_outer\n"); 1278 return false; 1279 } 1280 1281 if (!single_exit (loop)) 1282 { 1283 if (dump_file) 1284 { 1285 rtx insn = BB_END (loop->header); 1286 1287 fprintf (dump_file, "SMS loop many exits"); 1288 dump_insn_locator (insn); 1289 fprintf (dump_file, "\n"); 1290 } 1291 return false; 1292 } 1293 1294 if (! SIMPLE_SMS_LOOP_P (loop) && ! loop_single_full_bb_p (loop)) 1295 { 1296 if (dump_file) 1297 { 1298 rtx insn = BB_END (loop->header); 1299 1300 fprintf (dump_file, "SMS loop many BBs."); 1301 dump_insn_locator (insn); 1302 fprintf (dump_file, "\n"); 1303 } 1304 return false; 1305 } 1306 1307 return true; 1308 } 1309 1310 /* If there are more than one entry for the loop, 1311 make it one by splitting the first entry edge and 1312 redirecting the others to the new BB. */ 1313 static void 1314 canon_loop (struct loop *loop) 1315 { 1316 edge e; 1317 edge_iterator i; 1318 1319 /* Avoid annoying special cases of edges going to exit 1320 block. */ 1321 FOR_EACH_EDGE (e, i, EXIT_BLOCK_PTR->preds) 1322 if ((e->flags & EDGE_FALLTHRU) && (EDGE_COUNT (e->src->succs) > 1)) 1323 split_edge (e); 1324 1325 if (loop->latch == loop->header 1326 || EDGE_COUNT (loop->latch->succs) > 1) 1327 { 1328 FOR_EACH_EDGE (e, i, loop->header->preds) 1329 if (e->src == loop->latch) 1330 break; 1331 split_edge (e); 1332 } 1333 } 1334 1335 /* Setup infos. */ 1336 static void 1337 setup_sched_infos (void) 1338 { 1339 memcpy (&sms_common_sched_info, &haifa_common_sched_info, 1340 sizeof (sms_common_sched_info)); 1341 sms_common_sched_info.sched_pass_id = SCHED_SMS_PASS; 1342 common_sched_info = &sms_common_sched_info; 1343 1344 sched_deps_info = &sms_sched_deps_info; 1345 current_sched_info = &sms_sched_info; 1346 } 1347 1348 /* Probability in % that the sms-ed loop rolls enough so that optimized 1349 version may be entered. Just a guess. */ 1350 #define PROB_SMS_ENOUGH_ITERATIONS 80 1351 1352 /* Used to calculate the upper bound of ii. */ 1353 #define MAXII_FACTOR 2 1354 1355 /* Main entry point, perform SMS scheduling on the loops of the function 1356 that consist of single basic blocks. */ 1357 static void 1358 sms_schedule (void) 1359 { 1360 rtx insn; 1361 ddg_ptr *g_arr, g; 1362 int * node_order; 1363 int maxii, max_asap; 1364 loop_iterator li; 1365 partial_schedule_ptr ps; 1366 basic_block bb = NULL; 1367 struct loop *loop; 1368 basic_block condition_bb = NULL; 1369 edge latch_edge; 1370 gcov_type trip_count = 0; 1371 1372 loop_optimizer_init (LOOPS_HAVE_PREHEADERS 1373 | LOOPS_HAVE_RECORDED_EXITS); 1374 if (number_of_loops () <= 1) 1375 { 1376 loop_optimizer_finalize (); 1377 return; /* There are no loops to schedule. */ 1378 } 1379 1380 /* Initialize issue_rate. */ 1381 if (targetm.sched.issue_rate) 1382 { 1383 int temp = reload_completed; 1384 1385 reload_completed = 1; 1386 issue_rate = targetm.sched.issue_rate (); 1387 reload_completed = temp; 1388 } 1389 else 1390 issue_rate = 1; 1391 1392 /* Initialize the scheduler. */ 1393 setup_sched_infos (); 1394 haifa_sched_init (); 1395 1396 /* Allocate memory to hold the DDG array one entry for each loop. 1397 We use loop->num as index into this array. */ 1398 g_arr = XCNEWVEC (ddg_ptr, number_of_loops ()); 1399 1400 if (dump_file) 1401 { 1402 fprintf (dump_file, "\n\nSMS analysis phase\n"); 1403 fprintf (dump_file, "===================\n\n"); 1404 } 1405 1406 /* Build DDGs for all the relevant loops and hold them in G_ARR 1407 indexed by the loop index. */ 1408 FOR_EACH_LOOP (li, loop, 0) 1409 { 1410 rtx head, tail; 1411 rtx count_reg; 1412 1413 /* For debugging. */ 1414 if (dbg_cnt (sms_sched_loop) == false) 1415 { 1416 if (dump_file) 1417 fprintf (dump_file, "SMS reached max limit... \n"); 1418 1419 FOR_EACH_LOOP_BREAK (li); 1420 } 1421 1422 if (dump_file) 1423 { 1424 rtx insn = BB_END (loop->header); 1425 1426 fprintf (dump_file, "SMS loop num: %d", loop->num); 1427 dump_insn_locator (insn); 1428 fprintf (dump_file, "\n"); 1429 } 1430 1431 if (! loop_canon_p (loop)) 1432 continue; 1433 1434 if (! loop_single_full_bb_p (loop)) 1435 { 1436 if (dump_file) 1437 fprintf (dump_file, "SMS not loop_single_full_bb_p\n"); 1438 continue; 1439 } 1440 1441 bb = loop->header; 1442 1443 get_ebb_head_tail (bb, bb, &head, &tail); 1444 latch_edge = loop_latch_edge (loop); 1445 gcc_assert (single_exit (loop)); 1446 if (single_exit (loop)->count) 1447 trip_count = latch_edge->count / single_exit (loop)->count; 1448 1449 /* Perform SMS only on loops that their average count is above threshold. */ 1450 1451 if ( latch_edge->count 1452 && (latch_edge->count < single_exit (loop)->count * SMS_LOOP_AVERAGE_COUNT_THRESHOLD)) 1453 { 1454 if (dump_file) 1455 { 1456 dump_insn_locator (tail); 1457 fprintf (dump_file, "\nSMS single-bb-loop\n"); 1458 if (profile_info && flag_branch_probabilities) 1459 { 1460 fprintf (dump_file, "SMS loop-count "); 1461 fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, 1462 (HOST_WIDEST_INT) bb->count); 1463 fprintf (dump_file, "\n"); 1464 fprintf (dump_file, "SMS trip-count "); 1465 fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, 1466 (HOST_WIDEST_INT) trip_count); 1467 fprintf (dump_file, "\n"); 1468 fprintf (dump_file, "SMS profile-sum-max "); 1469 fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, 1470 (HOST_WIDEST_INT) profile_info->sum_max); 1471 fprintf (dump_file, "\n"); 1472 } 1473 } 1474 continue; 1475 } 1476 1477 /* Make sure this is a doloop. */ 1478 if ( !(count_reg = doloop_register_get (head, tail))) 1479 { 1480 if (dump_file) 1481 fprintf (dump_file, "SMS doloop_register_get failed\n"); 1482 continue; 1483 } 1484 1485 /* Don't handle BBs with calls or barriers 1486 or !single_set with the exception of instructions that include 1487 count_reg---these instructions are part of the control part 1488 that do-loop recognizes. 1489 ??? Should handle insns defining subregs. */ 1490 for (insn = head; insn != NEXT_INSN (tail); insn = NEXT_INSN (insn)) 1491 { 1492 rtx set; 1493 1494 if (CALL_P (insn) 1495 || BARRIER_P (insn) 1496 || (NONDEBUG_INSN_P (insn) && !JUMP_P (insn) 1497 && !single_set (insn) && GET_CODE (PATTERN (insn)) != USE 1498 && !reg_mentioned_p (count_reg, insn)) 1499 || (INSN_P (insn) && (set = single_set (insn)) 1500 && GET_CODE (SET_DEST (set)) == SUBREG)) 1501 break; 1502 } 1503 1504 if (insn != NEXT_INSN (tail)) 1505 { 1506 if (dump_file) 1507 { 1508 if (CALL_P (insn)) 1509 fprintf (dump_file, "SMS loop-with-call\n"); 1510 else if (BARRIER_P (insn)) 1511 fprintf (dump_file, "SMS loop-with-barrier\n"); 1512 else if ((NONDEBUG_INSN_P (insn) && !JUMP_P (insn) 1513 && !single_set (insn) && GET_CODE (PATTERN (insn)) != USE)) 1514 fprintf (dump_file, "SMS loop-with-not-single-set\n"); 1515 else 1516 fprintf (dump_file, "SMS loop with subreg in lhs\n"); 1517 print_rtl_single (dump_file, insn); 1518 } 1519 1520 continue; 1521 } 1522 1523 /* Always schedule the closing branch with the rest of the 1524 instructions. The branch is rotated to be in row ii-1 at the 1525 end of the scheduling procedure to make sure it's the last 1526 instruction in the iteration. */ 1527 if (! (g = create_ddg (bb, 1))) 1528 { 1529 if (dump_file) 1530 fprintf (dump_file, "SMS create_ddg failed\n"); 1531 continue; 1532 } 1533 1534 g_arr[loop->num] = g; 1535 if (dump_file) 1536 fprintf (dump_file, "...OK\n"); 1537 1538 } 1539 if (dump_file) 1540 { 1541 fprintf (dump_file, "\nSMS transformation phase\n"); 1542 fprintf (dump_file, "=========================\n\n"); 1543 } 1544 1545 /* We don't want to perform SMS on new loops - created by versioning. */ 1546 FOR_EACH_LOOP (li, loop, 0) 1547 { 1548 rtx head, tail; 1549 rtx count_reg, count_init; 1550 int mii, rec_mii, stage_count, min_cycle; 1551 HOST_WIDEST_INT loop_count = 0; 1552 bool opt_sc_p; 1553 1554 if (! (g = g_arr[loop->num])) 1555 continue; 1556 1557 if (dump_file) 1558 { 1559 rtx insn = BB_END (loop->header); 1560 1561 fprintf (dump_file, "SMS loop num: %d", loop->num); 1562 dump_insn_locator (insn); 1563 fprintf (dump_file, "\n"); 1564 1565 print_ddg (dump_file, g); 1566 } 1567 1568 get_ebb_head_tail (loop->header, loop->header, &head, &tail); 1569 1570 latch_edge = loop_latch_edge (loop); 1571 gcc_assert (single_exit (loop)); 1572 if (single_exit (loop)->count) 1573 trip_count = latch_edge->count / single_exit (loop)->count; 1574 1575 if (dump_file) 1576 { 1577 dump_insn_locator (tail); 1578 fprintf (dump_file, "\nSMS single-bb-loop\n"); 1579 if (profile_info && flag_branch_probabilities) 1580 { 1581 fprintf (dump_file, "SMS loop-count "); 1582 fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, 1583 (HOST_WIDEST_INT) bb->count); 1584 fprintf (dump_file, "\n"); 1585 fprintf (dump_file, "SMS profile-sum-max "); 1586 fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, 1587 (HOST_WIDEST_INT) profile_info->sum_max); 1588 fprintf (dump_file, "\n"); 1589 } 1590 fprintf (dump_file, "SMS doloop\n"); 1591 fprintf (dump_file, "SMS built-ddg %d\n", g->num_nodes); 1592 fprintf (dump_file, "SMS num-loads %d\n", g->num_loads); 1593 fprintf (dump_file, "SMS num-stores %d\n", g->num_stores); 1594 } 1595 1596 1597 /* In case of th loop have doloop register it gets special 1598 handling. */ 1599 count_init = NULL_RTX; 1600 if ((count_reg = doloop_register_get (head, tail))) 1601 { 1602 basic_block pre_header; 1603 1604 pre_header = loop_preheader_edge (loop)->src; 1605 count_init = const_iteration_count (count_reg, pre_header, 1606 &loop_count); 1607 } 1608 gcc_assert (count_reg); 1609 1610 if (dump_file && count_init) 1611 { 1612 fprintf (dump_file, "SMS const-doloop "); 1613 fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, 1614 loop_count); 1615 fprintf (dump_file, "\n"); 1616 } 1617 1618 node_order = XNEWVEC (int, g->num_nodes); 1619 1620 mii = 1; /* Need to pass some estimate of mii. */ 1621 rec_mii = sms_order_nodes (g, mii, node_order, &max_asap); 1622 mii = MAX (res_MII (g), rec_mii); 1623 maxii = MAX (max_asap, MAXII_FACTOR * mii); 1624 1625 if (dump_file) 1626 fprintf (dump_file, "SMS iis %d %d %d (rec_mii, mii, maxii)\n", 1627 rec_mii, mii, maxii); 1628 1629 for (;;) 1630 { 1631 set_node_sched_params (g); 1632 1633 stage_count = 0; 1634 opt_sc_p = false; 1635 ps = sms_schedule_by_order (g, mii, maxii, node_order); 1636 1637 if (ps) 1638 { 1639 /* Try to achieve optimized SC by normalizing the partial 1640 schedule (having the cycles start from cycle zero). 1641 The branch location must be placed in row ii-1 in the 1642 final scheduling. If failed, shift all instructions to 1643 position the branch in row ii-1. */ 1644 opt_sc_p = optimize_sc (ps, g); 1645 if (opt_sc_p) 1646 stage_count = calculate_stage_count (ps, 0); 1647 else 1648 { 1649 /* Bring the branch to cycle ii-1. */ 1650 int amount = (SCHED_TIME (g->closing_branch->cuid) 1651 - (ps->ii - 1)); 1652 1653 if (dump_file) 1654 fprintf (dump_file, "SMS schedule branch at cycle ii-1\n"); 1655 1656 stage_count = calculate_stage_count (ps, amount); 1657 } 1658 1659 gcc_assert (stage_count >= 1); 1660 } 1661 1662 /* The default value of PARAM_SMS_MIN_SC is 2 as stage count of 1663 1 means that there is no interleaving between iterations thus 1664 we let the scheduling passes do the job in this case. */ 1665 if (stage_count < PARAM_VALUE (PARAM_SMS_MIN_SC) 1666 || (count_init && (loop_count <= stage_count)) 1667 || (flag_branch_probabilities && (trip_count <= stage_count))) 1668 { 1669 if (dump_file) 1670 { 1671 fprintf (dump_file, "SMS failed... \n"); 1672 fprintf (dump_file, "SMS sched-failed (stage-count=%d," 1673 " loop-count=", stage_count); 1674 fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, loop_count); 1675 fprintf (dump_file, ", trip-count="); 1676 fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, trip_count); 1677 fprintf (dump_file, ")\n"); 1678 } 1679 break; 1680 } 1681 1682 if (!opt_sc_p) 1683 { 1684 /* Rotate the partial schedule to have the branch in row ii-1. */ 1685 int amount = SCHED_TIME (g->closing_branch->cuid) - (ps->ii - 1); 1686 1687 reset_sched_times (ps, amount); 1688 rotate_partial_schedule (ps, amount); 1689 } 1690 1691 set_columns_for_ps (ps); 1692 1693 min_cycle = PS_MIN_CYCLE (ps) - SMODULO (PS_MIN_CYCLE (ps), ps->ii); 1694 if (!schedule_reg_moves (ps)) 1695 { 1696 mii = ps->ii + 1; 1697 free_partial_schedule (ps); 1698 continue; 1699 } 1700 1701 /* Moves that handle incoming values might have been added 1702 to a new first stage. Bump the stage count if so. 1703 1704 ??? Perhaps we could consider rotating the schedule here 1705 instead? */ 1706 if (PS_MIN_CYCLE (ps) < min_cycle) 1707 { 1708 reset_sched_times (ps, 0); 1709 stage_count++; 1710 } 1711 1712 /* The stage count should now be correct without rotation. */ 1713 gcc_checking_assert (stage_count == calculate_stage_count (ps, 0)); 1714 PS_STAGE_COUNT (ps) = stage_count; 1715 1716 canon_loop (loop); 1717 1718 if (dump_file) 1719 { 1720 dump_insn_locator (tail); 1721 fprintf (dump_file, " SMS succeeded %d %d (with ii, sc)\n", 1722 ps->ii, stage_count); 1723 print_partial_schedule (ps, dump_file); 1724 } 1725 1726 /* case the BCT count is not known , Do loop-versioning */ 1727 if (count_reg && ! count_init) 1728 { 1729 rtx comp_rtx = gen_rtx_fmt_ee (GT, VOIDmode, count_reg, 1730 GEN_INT(stage_count)); 1731 unsigned prob = (PROB_SMS_ENOUGH_ITERATIONS 1732 * REG_BR_PROB_BASE) / 100; 1733 1734 loop_version (loop, comp_rtx, &condition_bb, 1735 prob, prob, REG_BR_PROB_BASE - prob, 1736 true); 1737 } 1738 1739 /* Set new iteration count of loop kernel. */ 1740 if (count_reg && count_init) 1741 SET_SRC (single_set (count_init)) = GEN_INT (loop_count 1742 - stage_count + 1); 1743 1744 /* Now apply the scheduled kernel to the RTL of the loop. */ 1745 permute_partial_schedule (ps, g->closing_branch->first_note); 1746 1747 /* Mark this loop as software pipelined so the later 1748 scheduling passes don't touch it. */ 1749 if (! flag_resched_modulo_sched) 1750 mark_loop_unsched (loop); 1751 1752 /* The life-info is not valid any more. */ 1753 df_set_bb_dirty (g->bb); 1754 1755 apply_reg_moves (ps); 1756 if (dump_file) 1757 print_node_sched_params (dump_file, g->num_nodes, ps); 1758 /* Generate prolog and epilog. */ 1759 generate_prolog_epilog (ps, loop, count_reg, count_init); 1760 break; 1761 } 1762 1763 free_partial_schedule (ps); 1764 VEC_free (node_sched_params, heap, node_sched_param_vec); 1765 free (node_order); 1766 free_ddg (g); 1767 } 1768 1769 free (g_arr); 1770 1771 /* Release scheduler data, needed until now because of DFA. */ 1772 haifa_sched_finish (); 1773 loop_optimizer_finalize (); 1774 } 1775 1776 /* The SMS scheduling algorithm itself 1777 ----------------------------------- 1778 Input: 'O' an ordered list of insns of a loop. 1779 Output: A scheduling of the loop - kernel, prolog, and epilogue. 1780 1781 'Q' is the empty Set 1782 'PS' is the partial schedule; it holds the currently scheduled nodes with 1783 their cycle/slot. 1784 'PSP' previously scheduled predecessors. 1785 'PSS' previously scheduled successors. 1786 't(u)' the cycle where u is scheduled. 1787 'l(u)' is the latency of u. 1788 'd(v,u)' is the dependence distance from v to u. 1789 'ASAP(u)' the earliest time at which u could be scheduled as computed in 1790 the node ordering phase. 1791 'check_hardware_resources_conflicts(u, PS, c)' 1792 run a trace around cycle/slot through DFA model 1793 to check resource conflicts involving instruction u 1794 at cycle c given the partial schedule PS. 1795 'add_to_partial_schedule_at_time(u, PS, c)' 1796 Add the node/instruction u to the partial schedule 1797 PS at time c. 1798 'calculate_register_pressure(PS)' 1799 Given a schedule of instructions, calculate the register 1800 pressure it implies. One implementation could be the 1801 maximum number of overlapping live ranges. 1802 'maxRP' The maximum allowed register pressure, it is usually derived from the number 1803 registers available in the hardware. 1804 1805 1. II = MII. 1806 2. PS = empty list 1807 3. for each node u in O in pre-computed order 1808 4. if (PSP(u) != Q && PSS(u) == Q) then 1809 5. Early_start(u) = max ( t(v) + l(v) - d(v,u)*II ) over all every v in PSP(u). 1810 6. start = Early_start; end = Early_start + II - 1; step = 1 1811 11. else if (PSP(u) == Q && PSS(u) != Q) then 1812 12. Late_start(u) = min ( t(v) - l(v) + d(v,u)*II ) over all every v in PSS(u). 1813 13. start = Late_start; end = Late_start - II + 1; step = -1 1814 14. else if (PSP(u) != Q && PSS(u) != Q) then 1815 15. Early_start(u) = max ( t(v) + l(v) - d(v,u)*II ) over all every v in PSP(u). 1816 16. Late_start(u) = min ( t(v) - l(v) + d(v,u)*II ) over all every v in PSS(u). 1817 17. start = Early_start; 1818 18. end = min(Early_start + II - 1 , Late_start); 1819 19. step = 1 1820 20. else "if (PSP(u) == Q && PSS(u) == Q)" 1821 21. start = ASAP(u); end = start + II - 1; step = 1 1822 22. endif 1823 1824 23. success = false 1825 24. for (c = start ; c != end ; c += step) 1826 25. if check_hardware_resources_conflicts(u, PS, c) then 1827 26. add_to_partial_schedule_at_time(u, PS, c) 1828 27. success = true 1829 28. break 1830 29. endif 1831 30. endfor 1832 31. if (success == false) then 1833 32. II = II + 1 1834 33. if (II > maxII) then 1835 34. finish - failed to schedule 1836 35. endif 1837 36. goto 2. 1838 37. endif 1839 38. endfor 1840 39. if (calculate_register_pressure(PS) > maxRP) then 1841 40. goto 32. 1842 41. endif 1843 42. compute epilogue & prologue 1844 43. finish - succeeded to schedule 1845 1846 ??? The algorithm restricts the scheduling window to II cycles. 1847 In rare cases, it may be better to allow windows of II+1 cycles. 1848 The window would then start and end on the same row, but with 1849 different "must precede" and "must follow" requirements. */ 1850 1851 /* A limit on the number of cycles that resource conflicts can span. ??? Should 1852 be provided by DFA, and be dependent on the type of insn scheduled. Currently 1853 set to 0 to save compile time. */ 1854 #define DFA_HISTORY SMS_DFA_HISTORY 1855 1856 /* A threshold for the number of repeated unsuccessful attempts to insert 1857 an empty row, before we flush the partial schedule and start over. */ 1858 #define MAX_SPLIT_NUM 10 1859 /* Given the partial schedule PS, this function calculates and returns the 1860 cycles in which we can schedule the node with the given index I. 1861 NOTE: Here we do the backtracking in SMS, in some special cases. We have 1862 noticed that there are several cases in which we fail to SMS the loop 1863 because the sched window of a node is empty due to tight data-deps. In 1864 such cases we want to unschedule some of the predecessors/successors 1865 until we get non-empty scheduling window. It returns -1 if the 1866 scheduling window is empty and zero otherwise. */ 1867 1868 static int 1869 get_sched_window (partial_schedule_ptr ps, ddg_node_ptr u_node, 1870 sbitmap sched_nodes, int ii, int *start_p, int *step_p, 1871 int *end_p) 1872 { 1873 int start, step, end; 1874 int early_start, late_start; 1875 ddg_edge_ptr e; 1876 sbitmap psp = sbitmap_alloc (ps->g->num_nodes); 1877 sbitmap pss = sbitmap_alloc (ps->g->num_nodes); 1878 sbitmap u_node_preds = NODE_PREDECESSORS (u_node); 1879 sbitmap u_node_succs = NODE_SUCCESSORS (u_node); 1880 int psp_not_empty; 1881 int pss_not_empty; 1882 int count_preds; 1883 int count_succs; 1884 1885 /* 1. compute sched window for u (start, end, step). */ 1886 sbitmap_zero (psp); 1887 sbitmap_zero (pss); 1888 psp_not_empty = sbitmap_a_and_b_cg (psp, u_node_preds, sched_nodes); 1889 pss_not_empty = sbitmap_a_and_b_cg (pss, u_node_succs, sched_nodes); 1890 1891 /* We first compute a forward range (start <= end), then decide whether 1892 to reverse it. */ 1893 early_start = INT_MIN; 1894 late_start = INT_MAX; 1895 start = INT_MIN; 1896 end = INT_MAX; 1897 step = 1; 1898 1899 count_preds = 0; 1900 count_succs = 0; 1901 1902 if (dump_file && (psp_not_empty || pss_not_empty)) 1903 { 1904 fprintf (dump_file, "\nAnalyzing dependencies for node %d (INSN %d)" 1905 "; ii = %d\n\n", u_node->cuid, INSN_UID (u_node->insn), ii); 1906 fprintf (dump_file, "%11s %11s %11s %11s %5s\n", 1907 "start", "early start", "late start", "end", "time"); 1908 fprintf (dump_file, "=========== =========== =========== ===========" 1909 " =====\n"); 1910 } 1911 /* Calculate early_start and limit end. Both bounds are inclusive. */ 1912 if (psp_not_empty) 1913 for (e = u_node->in; e != 0; e = e->next_in) 1914 { 1915 int v = e->src->cuid; 1916 1917 if (TEST_BIT (sched_nodes, v)) 1918 { 1919 int p_st = SCHED_TIME (v); 1920 int earliest = p_st + e->latency - (e->distance * ii); 1921 int latest = (e->data_type == MEM_DEP ? p_st + ii - 1 : INT_MAX); 1922 1923 if (dump_file) 1924 { 1925 fprintf (dump_file, "%11s %11d %11s %11d %5d", 1926 "", earliest, "", latest, p_st); 1927 print_ddg_edge (dump_file, e); 1928 fprintf (dump_file, "\n"); 1929 } 1930 1931 early_start = MAX (early_start, earliest); 1932 end = MIN (end, latest); 1933 1934 if (e->type == TRUE_DEP && e->data_type == REG_DEP) 1935 count_preds++; 1936 } 1937 } 1938 1939 /* Calculate late_start and limit start. Both bounds are inclusive. */ 1940 if (pss_not_empty) 1941 for (e = u_node->out; e != 0; e = e->next_out) 1942 { 1943 int v = e->dest->cuid; 1944 1945 if (TEST_BIT (sched_nodes, v)) 1946 { 1947 int s_st = SCHED_TIME (v); 1948 int earliest = (e->data_type == MEM_DEP ? s_st - ii + 1 : INT_MIN); 1949 int latest = s_st - e->latency + (e->distance * ii); 1950 1951 if (dump_file) 1952 { 1953 fprintf (dump_file, "%11d %11s %11d %11s %5d", 1954 earliest, "", latest, "", s_st); 1955 print_ddg_edge (dump_file, e); 1956 fprintf (dump_file, "\n"); 1957 } 1958 1959 start = MAX (start, earliest); 1960 late_start = MIN (late_start, latest); 1961 1962 if (e->type == TRUE_DEP && e->data_type == REG_DEP) 1963 count_succs++; 1964 } 1965 } 1966 1967 if (dump_file && (psp_not_empty || pss_not_empty)) 1968 { 1969 fprintf (dump_file, "----------- ----------- ----------- -----------" 1970 " -----\n"); 1971 fprintf (dump_file, "%11d %11d %11d %11d %5s %s\n", 1972 start, early_start, late_start, end, "", 1973 "(max, max, min, min)"); 1974 } 1975 1976 /* Get a target scheduling window no bigger than ii. */ 1977 if (early_start == INT_MIN && late_start == INT_MAX) 1978 early_start = NODE_ASAP (u_node); 1979 else if (early_start == INT_MIN) 1980 early_start = late_start - (ii - 1); 1981 late_start = MIN (late_start, early_start + (ii - 1)); 1982 1983 /* Apply memory dependence limits. */ 1984 start = MAX (start, early_start); 1985 end = MIN (end, late_start); 1986 1987 if (dump_file && (psp_not_empty || pss_not_empty)) 1988 fprintf (dump_file, "%11s %11d %11d %11s %5s final window\n", 1989 "", start, end, "", ""); 1990 1991 /* If there are at least as many successors as predecessors, schedule the 1992 node close to its successors. */ 1993 if (pss_not_empty && count_succs >= count_preds) 1994 { 1995 int tmp = end; 1996 end = start; 1997 start = tmp; 1998 step = -1; 1999 } 2000 2001 /* Now that we've finalized the window, make END an exclusive rather 2002 than an inclusive bound. */ 2003 end += step; 2004 2005 *start_p = start; 2006 *step_p = step; 2007 *end_p = end; 2008 sbitmap_free (psp); 2009 sbitmap_free (pss); 2010 2011 if ((start >= end && step == 1) || (start <= end && step == -1)) 2012 { 2013 if (dump_file) 2014 fprintf (dump_file, "\nEmpty window: start=%d, end=%d, step=%d\n", 2015 start, end, step); 2016 return -1; 2017 } 2018 2019 return 0; 2020 } 2021 2022 /* Calculate MUST_PRECEDE/MUST_FOLLOW bitmaps of U_NODE; which is the 2023 node currently been scheduled. At the end of the calculation 2024 MUST_PRECEDE/MUST_FOLLOW contains all predecessors/successors of 2025 U_NODE which are (1) already scheduled in the first/last row of 2026 U_NODE's scheduling window, (2) whose dependence inequality with U 2027 becomes an equality when U is scheduled in this same row, and (3) 2028 whose dependence latency is zero. 2029 2030 The first and last rows are calculated using the following parameters: 2031 START/END rows - The cycles that begins/ends the traversal on the window; 2032 searching for an empty cycle to schedule U_NODE. 2033 STEP - The direction in which we traverse the window. 2034 II - The initiation interval. */ 2035 2036 static void 2037 calculate_must_precede_follow (ddg_node_ptr u_node, int start, int end, 2038 int step, int ii, sbitmap sched_nodes, 2039 sbitmap must_precede, sbitmap must_follow) 2040 { 2041 ddg_edge_ptr e; 2042 int first_cycle_in_window, last_cycle_in_window; 2043 2044 gcc_assert (must_precede && must_follow); 2045 2046 /* Consider the following scheduling window: 2047 {first_cycle_in_window, first_cycle_in_window+1, ..., 2048 last_cycle_in_window}. If step is 1 then the following will be 2049 the order we traverse the window: {start=first_cycle_in_window, 2050 first_cycle_in_window+1, ..., end=last_cycle_in_window+1}, 2051 or {start=last_cycle_in_window, last_cycle_in_window-1, ..., 2052 end=first_cycle_in_window-1} if step is -1. */ 2053 first_cycle_in_window = (step == 1) ? start : end - step; 2054 last_cycle_in_window = (step == 1) ? end - step : start; 2055 2056 sbitmap_zero (must_precede); 2057 sbitmap_zero (must_follow); 2058 2059 if (dump_file) 2060 fprintf (dump_file, "\nmust_precede: "); 2061 2062 /* Instead of checking if: 2063 (SMODULO (SCHED_TIME (e->src), ii) == first_row_in_window) 2064 && ((SCHED_TIME (e->src) + e->latency - (e->distance * ii)) == 2065 first_cycle_in_window) 2066 && e->latency == 0 2067 we use the fact that latency is non-negative: 2068 SCHED_TIME (e->src) - (e->distance * ii) <= 2069 SCHED_TIME (e->src) + e->latency - (e->distance * ii)) <= 2070 first_cycle_in_window 2071 and check only if 2072 SCHED_TIME (e->src) - (e->distance * ii) == first_cycle_in_window */ 2073 for (e = u_node->in; e != 0; e = e->next_in) 2074 if (TEST_BIT (sched_nodes, e->src->cuid) 2075 && ((SCHED_TIME (e->src->cuid) - (e->distance * ii)) == 2076 first_cycle_in_window)) 2077 { 2078 if (dump_file) 2079 fprintf (dump_file, "%d ", e->src->cuid); 2080 2081 SET_BIT (must_precede, e->src->cuid); 2082 } 2083 2084 if (dump_file) 2085 fprintf (dump_file, "\nmust_follow: "); 2086 2087 /* Instead of checking if: 2088 (SMODULO (SCHED_TIME (e->dest), ii) == last_row_in_window) 2089 && ((SCHED_TIME (e->dest) - e->latency + (e->distance * ii)) == 2090 last_cycle_in_window) 2091 && e->latency == 0 2092 we use the fact that latency is non-negative: 2093 SCHED_TIME (e->dest) + (e->distance * ii) >= 2094 SCHED_TIME (e->dest) - e->latency + (e->distance * ii)) >= 2095 last_cycle_in_window 2096 and check only if 2097 SCHED_TIME (e->dest) + (e->distance * ii) == last_cycle_in_window */ 2098 for (e = u_node->out; e != 0; e = e->next_out) 2099 if (TEST_BIT (sched_nodes, e->dest->cuid) 2100 && ((SCHED_TIME (e->dest->cuid) + (e->distance * ii)) == 2101 last_cycle_in_window)) 2102 { 2103 if (dump_file) 2104 fprintf (dump_file, "%d ", e->dest->cuid); 2105 2106 SET_BIT (must_follow, e->dest->cuid); 2107 } 2108 2109 if (dump_file) 2110 fprintf (dump_file, "\n"); 2111 } 2112 2113 /* Return 1 if U_NODE can be scheduled in CYCLE. Use the following 2114 parameters to decide if that's possible: 2115 PS - The partial schedule. 2116 U - The serial number of U_NODE. 2117 NUM_SPLITS - The number of row splits made so far. 2118 MUST_PRECEDE - The nodes that must precede U_NODE. (only valid at 2119 the first row of the scheduling window) 2120 MUST_FOLLOW - The nodes that must follow U_NODE. (only valid at the 2121 last row of the scheduling window) */ 2122 2123 static bool 2124 try_scheduling_node_in_cycle (partial_schedule_ptr ps, 2125 int u, int cycle, sbitmap sched_nodes, 2126 int *num_splits, sbitmap must_precede, 2127 sbitmap must_follow) 2128 { 2129 ps_insn_ptr psi; 2130 bool success = 0; 2131 2132 verify_partial_schedule (ps, sched_nodes); 2133 psi = ps_add_node_check_conflicts (ps, u, cycle, must_precede, must_follow); 2134 if (psi) 2135 { 2136 SCHED_TIME (u) = cycle; 2137 SET_BIT (sched_nodes, u); 2138 success = 1; 2139 *num_splits = 0; 2140 if (dump_file) 2141 fprintf (dump_file, "Scheduled w/o split in %d\n", cycle); 2142 2143 } 2144 2145 return success; 2146 } 2147 2148 /* This function implements the scheduling algorithm for SMS according to the 2149 above algorithm. */ 2150 static partial_schedule_ptr 2151 sms_schedule_by_order (ddg_ptr g, int mii, int maxii, int *nodes_order) 2152 { 2153 int ii = mii; 2154 int i, c, success, num_splits = 0; 2155 int flush_and_start_over = true; 2156 int num_nodes = g->num_nodes; 2157 int start, end, step; /* Place together into one struct? */ 2158 sbitmap sched_nodes = sbitmap_alloc (num_nodes); 2159 sbitmap must_precede = sbitmap_alloc (num_nodes); 2160 sbitmap must_follow = sbitmap_alloc (num_nodes); 2161 sbitmap tobe_scheduled = sbitmap_alloc (num_nodes); 2162 2163 partial_schedule_ptr ps = create_partial_schedule (ii, g, DFA_HISTORY); 2164 2165 sbitmap_ones (tobe_scheduled); 2166 sbitmap_zero (sched_nodes); 2167 2168 while (flush_and_start_over && (ii < maxii)) 2169 { 2170 2171 if (dump_file) 2172 fprintf (dump_file, "Starting with ii=%d\n", ii); 2173 flush_and_start_over = false; 2174 sbitmap_zero (sched_nodes); 2175 2176 for (i = 0; i < num_nodes; i++) 2177 { 2178 int u = nodes_order[i]; 2179 ddg_node_ptr u_node = &ps->g->nodes[u]; 2180 rtx insn = u_node->insn; 2181 2182 if (!NONDEBUG_INSN_P (insn)) 2183 { 2184 RESET_BIT (tobe_scheduled, u); 2185 continue; 2186 } 2187 2188 if (TEST_BIT (sched_nodes, u)) 2189 continue; 2190 2191 /* Try to get non-empty scheduling window. */ 2192 success = 0; 2193 if (get_sched_window (ps, u_node, sched_nodes, ii, &start, 2194 &step, &end) == 0) 2195 { 2196 if (dump_file) 2197 fprintf (dump_file, "\nTrying to schedule node %d " 2198 "INSN = %d in (%d .. %d) step %d\n", u, (INSN_UID 2199 (g->nodes[u].insn)), start, end, step); 2200 2201 gcc_assert ((step > 0 && start < end) 2202 || (step < 0 && start > end)); 2203 2204 calculate_must_precede_follow (u_node, start, end, step, ii, 2205 sched_nodes, must_precede, 2206 must_follow); 2207 2208 for (c = start; c != end; c += step) 2209 { 2210 sbitmap tmp_precede, tmp_follow; 2211 2212 set_must_precede_follow (&tmp_follow, must_follow, 2213 &tmp_precede, must_precede, 2214 c, start, end, step); 2215 success = 2216 try_scheduling_node_in_cycle (ps, u, c, 2217 sched_nodes, 2218 &num_splits, tmp_precede, 2219 tmp_follow); 2220 if (success) 2221 break; 2222 } 2223 2224 verify_partial_schedule (ps, sched_nodes); 2225 } 2226 if (!success) 2227 { 2228 int split_row; 2229 2230 if (ii++ == maxii) 2231 break; 2232 2233 if (num_splits >= MAX_SPLIT_NUM) 2234 { 2235 num_splits = 0; 2236 flush_and_start_over = true; 2237 verify_partial_schedule (ps, sched_nodes); 2238 reset_partial_schedule (ps, ii); 2239 verify_partial_schedule (ps, sched_nodes); 2240 break; 2241 } 2242 2243 num_splits++; 2244 /* The scheduling window is exclusive of 'end' 2245 whereas compute_split_window() expects an inclusive, 2246 ordered range. */ 2247 if (step == 1) 2248 split_row = compute_split_row (sched_nodes, start, end - 1, 2249 ps->ii, u_node); 2250 else 2251 split_row = compute_split_row (sched_nodes, end + 1, start, 2252 ps->ii, u_node); 2253 2254 ps_insert_empty_row (ps, split_row, sched_nodes); 2255 i--; /* Go back and retry node i. */ 2256 2257 if (dump_file) 2258 fprintf (dump_file, "num_splits=%d\n", num_splits); 2259 } 2260 2261 /* ??? If (success), check register pressure estimates. */ 2262 } /* Continue with next node. */ 2263 } /* While flush_and_start_over. */ 2264 if (ii >= maxii) 2265 { 2266 free_partial_schedule (ps); 2267 ps = NULL; 2268 } 2269 else 2270 gcc_assert (sbitmap_equal (tobe_scheduled, sched_nodes)); 2271 2272 sbitmap_free (sched_nodes); 2273 sbitmap_free (must_precede); 2274 sbitmap_free (must_follow); 2275 sbitmap_free (tobe_scheduled); 2276 2277 return ps; 2278 } 2279 2280 /* This function inserts a new empty row into PS at the position 2281 according to SPLITROW, keeping all already scheduled instructions 2282 intact and updating their SCHED_TIME and cycle accordingly. */ 2283 static void 2284 ps_insert_empty_row (partial_schedule_ptr ps, int split_row, 2285 sbitmap sched_nodes) 2286 { 2287 ps_insn_ptr crr_insn; 2288 ps_insn_ptr *rows_new; 2289 int ii = ps->ii; 2290 int new_ii = ii + 1; 2291 int row; 2292 int *rows_length_new; 2293 2294 verify_partial_schedule (ps, sched_nodes); 2295 2296 /* We normalize sched_time and rotate ps to have only non-negative sched 2297 times, for simplicity of updating cycles after inserting new row. */ 2298 split_row -= ps->min_cycle; 2299 split_row = SMODULO (split_row, ii); 2300 if (dump_file) 2301 fprintf (dump_file, "split_row=%d\n", split_row); 2302 2303 reset_sched_times (ps, PS_MIN_CYCLE (ps)); 2304 rotate_partial_schedule (ps, PS_MIN_CYCLE (ps)); 2305 2306 rows_new = (ps_insn_ptr *) xcalloc (new_ii, sizeof (ps_insn_ptr)); 2307 rows_length_new = (int *) xcalloc (new_ii, sizeof (int)); 2308 for (row = 0; row < split_row; row++) 2309 { 2310 rows_new[row] = ps->rows[row]; 2311 rows_length_new[row] = ps->rows_length[row]; 2312 ps->rows[row] = NULL; 2313 for (crr_insn = rows_new[row]; 2314 crr_insn; crr_insn = crr_insn->next_in_row) 2315 { 2316 int u = crr_insn->id; 2317 int new_time = SCHED_TIME (u) + (SCHED_TIME (u) / ii); 2318 2319 SCHED_TIME (u) = new_time; 2320 crr_insn->cycle = new_time; 2321 SCHED_ROW (u) = new_time % new_ii; 2322 SCHED_STAGE (u) = new_time / new_ii; 2323 } 2324 2325 } 2326 2327 rows_new[split_row] = NULL; 2328 2329 for (row = split_row; row < ii; row++) 2330 { 2331 rows_new[row + 1] = ps->rows[row]; 2332 rows_length_new[row + 1] = ps->rows_length[row]; 2333 ps->rows[row] = NULL; 2334 for (crr_insn = rows_new[row + 1]; 2335 crr_insn; crr_insn = crr_insn->next_in_row) 2336 { 2337 int u = crr_insn->id; 2338 int new_time = SCHED_TIME (u) + (SCHED_TIME (u) / ii) + 1; 2339 2340 SCHED_TIME (u) = new_time; 2341 crr_insn->cycle = new_time; 2342 SCHED_ROW (u) = new_time % new_ii; 2343 SCHED_STAGE (u) = new_time / new_ii; 2344 } 2345 } 2346 2347 /* Updating ps. */ 2348 ps->min_cycle = ps->min_cycle + ps->min_cycle / ii 2349 + (SMODULO (ps->min_cycle, ii) >= split_row ? 1 : 0); 2350 ps->max_cycle = ps->max_cycle + ps->max_cycle / ii 2351 + (SMODULO (ps->max_cycle, ii) >= split_row ? 1 : 0); 2352 free (ps->rows); 2353 ps->rows = rows_new; 2354 free (ps->rows_length); 2355 ps->rows_length = rows_length_new; 2356 ps->ii = new_ii; 2357 gcc_assert (ps->min_cycle >= 0); 2358 2359 verify_partial_schedule (ps, sched_nodes); 2360 2361 if (dump_file) 2362 fprintf (dump_file, "min_cycle=%d, max_cycle=%d\n", ps->min_cycle, 2363 ps->max_cycle); 2364 } 2365 2366 /* Given U_NODE which is the node that failed to be scheduled; LOW and 2367 UP which are the boundaries of it's scheduling window; compute using 2368 SCHED_NODES and II a row in the partial schedule that can be split 2369 which will separate a critical predecessor from a critical successor 2370 thereby expanding the window, and return it. */ 2371 static int 2372 compute_split_row (sbitmap sched_nodes, int low, int up, int ii, 2373 ddg_node_ptr u_node) 2374 { 2375 ddg_edge_ptr e; 2376 int lower = INT_MIN, upper = INT_MAX; 2377 int crit_pred = -1; 2378 int crit_succ = -1; 2379 int crit_cycle; 2380 2381 for (e = u_node->in; e != 0; e = e->next_in) 2382 { 2383 int v = e->src->cuid; 2384 2385 if (TEST_BIT (sched_nodes, v) 2386 && (low == SCHED_TIME (v) + e->latency - (e->distance * ii))) 2387 if (SCHED_TIME (v) > lower) 2388 { 2389 crit_pred = v; 2390 lower = SCHED_TIME (v); 2391 } 2392 } 2393 2394 if (crit_pred >= 0) 2395 { 2396 crit_cycle = SCHED_TIME (crit_pred) + 1; 2397 return SMODULO (crit_cycle, ii); 2398 } 2399 2400 for (e = u_node->out; e != 0; e = e->next_out) 2401 { 2402 int v = e->dest->cuid; 2403 2404 if (TEST_BIT (sched_nodes, v) 2405 && (up == SCHED_TIME (v) - e->latency + (e->distance * ii))) 2406 if (SCHED_TIME (v) < upper) 2407 { 2408 crit_succ = v; 2409 upper = SCHED_TIME (v); 2410 } 2411 } 2412 2413 if (crit_succ >= 0) 2414 { 2415 crit_cycle = SCHED_TIME (crit_succ); 2416 return SMODULO (crit_cycle, ii); 2417 } 2418 2419 if (dump_file) 2420 fprintf (dump_file, "Both crit_pred and crit_succ are NULL\n"); 2421 2422 return SMODULO ((low + up + 1) / 2, ii); 2423 } 2424 2425 static void 2426 verify_partial_schedule (partial_schedule_ptr ps, sbitmap sched_nodes) 2427 { 2428 int row; 2429 ps_insn_ptr crr_insn; 2430 2431 for (row = 0; row < ps->ii; row++) 2432 { 2433 int length = 0; 2434 2435 for (crr_insn = ps->rows[row]; crr_insn; crr_insn = crr_insn->next_in_row) 2436 { 2437 int u = crr_insn->id; 2438 2439 length++; 2440 gcc_assert (TEST_BIT (sched_nodes, u)); 2441 /* ??? Test also that all nodes of sched_nodes are in ps, perhaps by 2442 popcount (sched_nodes) == number of insns in ps. */ 2443 gcc_assert (SCHED_TIME (u) >= ps->min_cycle); 2444 gcc_assert (SCHED_TIME (u) <= ps->max_cycle); 2445 } 2446 2447 gcc_assert (ps->rows_length[row] == length); 2448 } 2449 } 2450 2451 2452 /* This page implements the algorithm for ordering the nodes of a DDG 2453 for modulo scheduling, activated through the 2454 "int sms_order_nodes (ddg_ptr, int mii, int * result)" API. */ 2455 2456 #define ORDER_PARAMS(x) ((struct node_order_params *) (x)->aux.info) 2457 #define ASAP(x) (ORDER_PARAMS ((x))->asap) 2458 #define ALAP(x) (ORDER_PARAMS ((x))->alap) 2459 #define HEIGHT(x) (ORDER_PARAMS ((x))->height) 2460 #define MOB(x) (ALAP ((x)) - ASAP ((x))) 2461 #define DEPTH(x) (ASAP ((x))) 2462 2463 typedef struct node_order_params * nopa; 2464 2465 static void order_nodes_of_sccs (ddg_all_sccs_ptr, int * result); 2466 static int order_nodes_in_scc (ddg_ptr, sbitmap, sbitmap, int*, int); 2467 static nopa calculate_order_params (ddg_ptr, int, int *); 2468 static int find_max_asap (ddg_ptr, sbitmap); 2469 static int find_max_hv_min_mob (ddg_ptr, sbitmap); 2470 static int find_max_dv_min_mob (ddg_ptr, sbitmap); 2471 2472 enum sms_direction {BOTTOMUP, TOPDOWN}; 2473 2474 struct node_order_params 2475 { 2476 int asap; 2477 int alap; 2478 int height; 2479 }; 2480 2481 /* Check if NODE_ORDER contains a permutation of 0 .. NUM_NODES-1. */ 2482 static void 2483 check_nodes_order (int *node_order, int num_nodes) 2484 { 2485 int i; 2486 sbitmap tmp = sbitmap_alloc (num_nodes); 2487 2488 sbitmap_zero (tmp); 2489 2490 if (dump_file) 2491 fprintf (dump_file, "SMS final nodes order: \n"); 2492 2493 for (i = 0; i < num_nodes; i++) 2494 { 2495 int u = node_order[i]; 2496 2497 if (dump_file) 2498 fprintf (dump_file, "%d ", u); 2499 gcc_assert (u < num_nodes && u >= 0 && !TEST_BIT (tmp, u)); 2500 2501 SET_BIT (tmp, u); 2502 } 2503 2504 if (dump_file) 2505 fprintf (dump_file, "\n"); 2506 2507 sbitmap_free (tmp); 2508 } 2509 2510 /* Order the nodes of G for scheduling and pass the result in 2511 NODE_ORDER. Also set aux.count of each node to ASAP. 2512 Put maximal ASAP to PMAX_ASAP. Return the recMII for the given DDG. */ 2513 static int 2514 sms_order_nodes (ddg_ptr g, int mii, int * node_order, int *pmax_asap) 2515 { 2516 int i; 2517 int rec_mii = 0; 2518 ddg_all_sccs_ptr sccs = create_ddg_all_sccs (g); 2519 2520 nopa nops = calculate_order_params (g, mii, pmax_asap); 2521 2522 if (dump_file) 2523 print_sccs (dump_file, sccs, g); 2524 2525 order_nodes_of_sccs (sccs, node_order); 2526 2527 if (sccs->num_sccs > 0) 2528 /* First SCC has the largest recurrence_length. */ 2529 rec_mii = sccs->sccs[0]->recurrence_length; 2530 2531 /* Save ASAP before destroying node_order_params. */ 2532 for (i = 0; i < g->num_nodes; i++) 2533 { 2534 ddg_node_ptr v = &g->nodes[i]; 2535 v->aux.count = ASAP (v); 2536 } 2537 2538 free (nops); 2539 free_ddg_all_sccs (sccs); 2540 check_nodes_order (node_order, g->num_nodes); 2541 2542 return rec_mii; 2543 } 2544 2545 static void 2546 order_nodes_of_sccs (ddg_all_sccs_ptr all_sccs, int * node_order) 2547 { 2548 int i, pos = 0; 2549 ddg_ptr g = all_sccs->ddg; 2550 int num_nodes = g->num_nodes; 2551 sbitmap prev_sccs = sbitmap_alloc (num_nodes); 2552 sbitmap on_path = sbitmap_alloc (num_nodes); 2553 sbitmap tmp = sbitmap_alloc (num_nodes); 2554 sbitmap ones = sbitmap_alloc (num_nodes); 2555 2556 sbitmap_zero (prev_sccs); 2557 sbitmap_ones (ones); 2558 2559 /* Perform the node ordering starting from the SCC with the highest recMII. 2560 For each SCC order the nodes according to their ASAP/ALAP/HEIGHT etc. */ 2561 for (i = 0; i < all_sccs->num_sccs; i++) 2562 { 2563 ddg_scc_ptr scc = all_sccs->sccs[i]; 2564 2565 /* Add nodes on paths from previous SCCs to the current SCC. */ 2566 find_nodes_on_paths (on_path, g, prev_sccs, scc->nodes); 2567 sbitmap_a_or_b (tmp, scc->nodes, on_path); 2568 2569 /* Add nodes on paths from the current SCC to previous SCCs. */ 2570 find_nodes_on_paths (on_path, g, scc->nodes, prev_sccs); 2571 sbitmap_a_or_b (tmp, tmp, on_path); 2572 2573 /* Remove nodes of previous SCCs from current extended SCC. */ 2574 sbitmap_difference (tmp, tmp, prev_sccs); 2575 2576 pos = order_nodes_in_scc (g, prev_sccs, tmp, node_order, pos); 2577 /* Above call to order_nodes_in_scc updated prev_sccs |= tmp. */ 2578 } 2579 2580 /* Handle the remaining nodes that do not belong to any scc. Each call 2581 to order_nodes_in_scc handles a single connected component. */ 2582 while (pos < g->num_nodes) 2583 { 2584 sbitmap_difference (tmp, ones, prev_sccs); 2585 pos = order_nodes_in_scc (g, prev_sccs, tmp, node_order, pos); 2586 } 2587 sbitmap_free (prev_sccs); 2588 sbitmap_free (on_path); 2589 sbitmap_free (tmp); 2590 sbitmap_free (ones); 2591 } 2592 2593 /* MII is needed if we consider backarcs (that do not close recursive cycles). */ 2594 static struct node_order_params * 2595 calculate_order_params (ddg_ptr g, int mii ATTRIBUTE_UNUSED, int *pmax_asap) 2596 { 2597 int u; 2598 int max_asap; 2599 int num_nodes = g->num_nodes; 2600 ddg_edge_ptr e; 2601 /* Allocate a place to hold ordering params for each node in the DDG. */ 2602 nopa node_order_params_arr; 2603 2604 /* Initialize of ASAP/ALAP/HEIGHT to zero. */ 2605 node_order_params_arr = (nopa) xcalloc (num_nodes, 2606 sizeof (struct node_order_params)); 2607 2608 /* Set the aux pointer of each node to point to its order_params structure. */ 2609 for (u = 0; u < num_nodes; u++) 2610 g->nodes[u].aux.info = &node_order_params_arr[u]; 2611 2612 /* Disregarding a backarc from each recursive cycle to obtain a DAG, 2613 calculate ASAP, ALAP, mobility, distance, and height for each node 2614 in the dependence (direct acyclic) graph. */ 2615 2616 /* We assume that the nodes in the array are in topological order. */ 2617 2618 max_asap = 0; 2619 for (u = 0; u < num_nodes; u++) 2620 { 2621 ddg_node_ptr u_node = &g->nodes[u]; 2622 2623 ASAP (u_node) = 0; 2624 for (e = u_node->in; e; e = e->next_in) 2625 if (e->distance == 0) 2626 ASAP (u_node) = MAX (ASAP (u_node), 2627 ASAP (e->src) + e->latency); 2628 max_asap = MAX (max_asap, ASAP (u_node)); 2629 } 2630 2631 for (u = num_nodes - 1; u > -1; u--) 2632 { 2633 ddg_node_ptr u_node = &g->nodes[u]; 2634 2635 ALAP (u_node) = max_asap; 2636 HEIGHT (u_node) = 0; 2637 for (e = u_node->out; e; e = e->next_out) 2638 if (e->distance == 0) 2639 { 2640 ALAP (u_node) = MIN (ALAP (u_node), 2641 ALAP (e->dest) - e->latency); 2642 HEIGHT (u_node) = MAX (HEIGHT (u_node), 2643 HEIGHT (e->dest) + e->latency); 2644 } 2645 } 2646 if (dump_file) 2647 { 2648 fprintf (dump_file, "\nOrder params\n"); 2649 for (u = 0; u < num_nodes; u++) 2650 { 2651 ddg_node_ptr u_node = &g->nodes[u]; 2652 2653 fprintf (dump_file, "node %d, ASAP: %d, ALAP: %d, HEIGHT: %d\n", u, 2654 ASAP (u_node), ALAP (u_node), HEIGHT (u_node)); 2655 } 2656 } 2657 2658 *pmax_asap = max_asap; 2659 return node_order_params_arr; 2660 } 2661 2662 static int 2663 find_max_asap (ddg_ptr g, sbitmap nodes) 2664 { 2665 unsigned int u = 0; 2666 int max_asap = -1; 2667 int result = -1; 2668 sbitmap_iterator sbi; 2669 2670 EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi) 2671 { 2672 ddg_node_ptr u_node = &g->nodes[u]; 2673 2674 if (max_asap < ASAP (u_node)) 2675 { 2676 max_asap = ASAP (u_node); 2677 result = u; 2678 } 2679 } 2680 return result; 2681 } 2682 2683 static int 2684 find_max_hv_min_mob (ddg_ptr g, sbitmap nodes) 2685 { 2686 unsigned int u = 0; 2687 int max_hv = -1; 2688 int min_mob = INT_MAX; 2689 int result = -1; 2690 sbitmap_iterator sbi; 2691 2692 EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi) 2693 { 2694 ddg_node_ptr u_node = &g->nodes[u]; 2695 2696 if (max_hv < HEIGHT (u_node)) 2697 { 2698 max_hv = HEIGHT (u_node); 2699 min_mob = MOB (u_node); 2700 result = u; 2701 } 2702 else if ((max_hv == HEIGHT (u_node)) 2703 && (min_mob > MOB (u_node))) 2704 { 2705 min_mob = MOB (u_node); 2706 result = u; 2707 } 2708 } 2709 return result; 2710 } 2711 2712 static int 2713 find_max_dv_min_mob (ddg_ptr g, sbitmap nodes) 2714 { 2715 unsigned int u = 0; 2716 int max_dv = -1; 2717 int min_mob = INT_MAX; 2718 int result = -1; 2719 sbitmap_iterator sbi; 2720 2721 EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi) 2722 { 2723 ddg_node_ptr u_node = &g->nodes[u]; 2724 2725 if (max_dv < DEPTH (u_node)) 2726 { 2727 max_dv = DEPTH (u_node); 2728 min_mob = MOB (u_node); 2729 result = u; 2730 } 2731 else if ((max_dv == DEPTH (u_node)) 2732 && (min_mob > MOB (u_node))) 2733 { 2734 min_mob = MOB (u_node); 2735 result = u; 2736 } 2737 } 2738 return result; 2739 } 2740 2741 /* Places the nodes of SCC into the NODE_ORDER array starting 2742 at position POS, according to the SMS ordering algorithm. 2743 NODES_ORDERED (in&out parameter) holds the bitset of all nodes in 2744 the NODE_ORDER array, starting from position zero. */ 2745 static int 2746 order_nodes_in_scc (ddg_ptr g, sbitmap nodes_ordered, sbitmap scc, 2747 int * node_order, int pos) 2748 { 2749 enum sms_direction dir; 2750 int num_nodes = g->num_nodes; 2751 sbitmap workset = sbitmap_alloc (num_nodes); 2752 sbitmap tmp = sbitmap_alloc (num_nodes); 2753 sbitmap zero_bitmap = sbitmap_alloc (num_nodes); 2754 sbitmap predecessors = sbitmap_alloc (num_nodes); 2755 sbitmap successors = sbitmap_alloc (num_nodes); 2756 2757 sbitmap_zero (predecessors); 2758 find_predecessors (predecessors, g, nodes_ordered); 2759 2760 sbitmap_zero (successors); 2761 find_successors (successors, g, nodes_ordered); 2762 2763 sbitmap_zero (tmp); 2764 if (sbitmap_a_and_b_cg (tmp, predecessors, scc)) 2765 { 2766 sbitmap_copy (workset, tmp); 2767 dir = BOTTOMUP; 2768 } 2769 else if (sbitmap_a_and_b_cg (tmp, successors, scc)) 2770 { 2771 sbitmap_copy (workset, tmp); 2772 dir = TOPDOWN; 2773 } 2774 else 2775 { 2776 int u; 2777 2778 sbitmap_zero (workset); 2779 if ((u = find_max_asap (g, scc)) >= 0) 2780 SET_BIT (workset, u); 2781 dir = BOTTOMUP; 2782 } 2783 2784 sbitmap_zero (zero_bitmap); 2785 while (!sbitmap_equal (workset, zero_bitmap)) 2786 { 2787 int v; 2788 ddg_node_ptr v_node; 2789 sbitmap v_node_preds; 2790 sbitmap v_node_succs; 2791 2792 if (dir == TOPDOWN) 2793 { 2794 while (!sbitmap_equal (workset, zero_bitmap)) 2795 { 2796 v = find_max_hv_min_mob (g, workset); 2797 v_node = &g->nodes[v]; 2798 node_order[pos++] = v; 2799 v_node_succs = NODE_SUCCESSORS (v_node); 2800 sbitmap_a_and_b (tmp, v_node_succs, scc); 2801 2802 /* Don't consider the already ordered successors again. */ 2803 sbitmap_difference (tmp, tmp, nodes_ordered); 2804 sbitmap_a_or_b (workset, workset, tmp); 2805 RESET_BIT (workset, v); 2806 SET_BIT (nodes_ordered, v); 2807 } 2808 dir = BOTTOMUP; 2809 sbitmap_zero (predecessors); 2810 find_predecessors (predecessors, g, nodes_ordered); 2811 sbitmap_a_and_b (workset, predecessors, scc); 2812 } 2813 else 2814 { 2815 while (!sbitmap_equal (workset, zero_bitmap)) 2816 { 2817 v = find_max_dv_min_mob (g, workset); 2818 v_node = &g->nodes[v]; 2819 node_order[pos++] = v; 2820 v_node_preds = NODE_PREDECESSORS (v_node); 2821 sbitmap_a_and_b (tmp, v_node_preds, scc); 2822 2823 /* Don't consider the already ordered predecessors again. */ 2824 sbitmap_difference (tmp, tmp, nodes_ordered); 2825 sbitmap_a_or_b (workset, workset, tmp); 2826 RESET_BIT (workset, v); 2827 SET_BIT (nodes_ordered, v); 2828 } 2829 dir = TOPDOWN; 2830 sbitmap_zero (successors); 2831 find_successors (successors, g, nodes_ordered); 2832 sbitmap_a_and_b (workset, successors, scc); 2833 } 2834 } 2835 sbitmap_free (tmp); 2836 sbitmap_free (workset); 2837 sbitmap_free (zero_bitmap); 2838 sbitmap_free (predecessors); 2839 sbitmap_free (successors); 2840 return pos; 2841 } 2842 2843 2844 /* This page contains functions for manipulating partial-schedules during 2845 modulo scheduling. */ 2846 2847 /* Create a partial schedule and allocate a memory to hold II rows. */ 2848 2849 static partial_schedule_ptr 2850 create_partial_schedule (int ii, ddg_ptr g, int history) 2851 { 2852 partial_schedule_ptr ps = XNEW (struct partial_schedule); 2853 ps->rows = (ps_insn_ptr *) xcalloc (ii, sizeof (ps_insn_ptr)); 2854 ps->rows_length = (int *) xcalloc (ii, sizeof (int)); 2855 ps->reg_moves = NULL; 2856 ps->ii = ii; 2857 ps->history = history; 2858 ps->min_cycle = INT_MAX; 2859 ps->max_cycle = INT_MIN; 2860 ps->g = g; 2861 2862 return ps; 2863 } 2864 2865 /* Free the PS_INSNs in rows array of the given partial schedule. 2866 ??? Consider caching the PS_INSN's. */ 2867 static void 2868 free_ps_insns (partial_schedule_ptr ps) 2869 { 2870 int i; 2871 2872 for (i = 0; i < ps->ii; i++) 2873 { 2874 while (ps->rows[i]) 2875 { 2876 ps_insn_ptr ps_insn = ps->rows[i]->next_in_row; 2877 2878 free (ps->rows[i]); 2879 ps->rows[i] = ps_insn; 2880 } 2881 ps->rows[i] = NULL; 2882 } 2883 } 2884 2885 /* Free all the memory allocated to the partial schedule. */ 2886 2887 static void 2888 free_partial_schedule (partial_schedule_ptr ps) 2889 { 2890 ps_reg_move_info *move; 2891 unsigned int i; 2892 2893 if (!ps) 2894 return; 2895 2896 FOR_EACH_VEC_ELT (ps_reg_move_info, ps->reg_moves, i, move) 2897 sbitmap_free (move->uses); 2898 VEC_free (ps_reg_move_info, heap, ps->reg_moves); 2899 2900 free_ps_insns (ps); 2901 free (ps->rows); 2902 free (ps->rows_length); 2903 free (ps); 2904 } 2905 2906 /* Clear the rows array with its PS_INSNs, and create a new one with 2907 NEW_II rows. */ 2908 2909 static void 2910 reset_partial_schedule (partial_schedule_ptr ps, int new_ii) 2911 { 2912 if (!ps) 2913 return; 2914 free_ps_insns (ps); 2915 if (new_ii == ps->ii) 2916 return; 2917 ps->rows = (ps_insn_ptr *) xrealloc (ps->rows, new_ii 2918 * sizeof (ps_insn_ptr)); 2919 memset (ps->rows, 0, new_ii * sizeof (ps_insn_ptr)); 2920 ps->rows_length = (int *) xrealloc (ps->rows_length, new_ii * sizeof (int)); 2921 memset (ps->rows_length, 0, new_ii * sizeof (int)); 2922 ps->ii = new_ii; 2923 ps->min_cycle = INT_MAX; 2924 ps->max_cycle = INT_MIN; 2925 } 2926 2927 /* Prints the partial schedule as an ii rows array, for each rows 2928 print the ids of the insns in it. */ 2929 void 2930 print_partial_schedule (partial_schedule_ptr ps, FILE *dump) 2931 { 2932 int i; 2933 2934 for (i = 0; i < ps->ii; i++) 2935 { 2936 ps_insn_ptr ps_i = ps->rows[i]; 2937 2938 fprintf (dump, "\n[ROW %d ]: ", i); 2939 while (ps_i) 2940 { 2941 rtx insn = ps_rtl_insn (ps, ps_i->id); 2942 2943 if (JUMP_P (insn)) 2944 fprintf (dump, "%d (branch), ", INSN_UID (insn)); 2945 else 2946 fprintf (dump, "%d, ", INSN_UID (insn)); 2947 2948 ps_i = ps_i->next_in_row; 2949 } 2950 } 2951 } 2952 2953 /* Creates an object of PS_INSN and initializes it to the given parameters. */ 2954 static ps_insn_ptr 2955 create_ps_insn (int id, int cycle) 2956 { 2957 ps_insn_ptr ps_i = XNEW (struct ps_insn); 2958 2959 ps_i->id = id; 2960 ps_i->next_in_row = NULL; 2961 ps_i->prev_in_row = NULL; 2962 ps_i->cycle = cycle; 2963 2964 return ps_i; 2965 } 2966 2967 2968 /* Removes the given PS_INSN from the partial schedule. */ 2969 static void 2970 remove_node_from_ps (partial_schedule_ptr ps, ps_insn_ptr ps_i) 2971 { 2972 int row; 2973 2974 gcc_assert (ps && ps_i); 2975 2976 row = SMODULO (ps_i->cycle, ps->ii); 2977 if (! ps_i->prev_in_row) 2978 { 2979 gcc_assert (ps_i == ps->rows[row]); 2980 ps->rows[row] = ps_i->next_in_row; 2981 if (ps->rows[row]) 2982 ps->rows[row]->prev_in_row = NULL; 2983 } 2984 else 2985 { 2986 ps_i->prev_in_row->next_in_row = ps_i->next_in_row; 2987 if (ps_i->next_in_row) 2988 ps_i->next_in_row->prev_in_row = ps_i->prev_in_row; 2989 } 2990 2991 ps->rows_length[row] -= 1; 2992 free (ps_i); 2993 return; 2994 } 2995 2996 /* Unlike what literature describes for modulo scheduling (which focuses 2997 on VLIW machines) the order of the instructions inside a cycle is 2998 important. Given the bitmaps MUST_FOLLOW and MUST_PRECEDE we know 2999 where the current instruction should go relative to the already 3000 scheduled instructions in the given cycle. Go over these 3001 instructions and find the first possible column to put it in. */ 3002 static bool 3003 ps_insn_find_column (partial_schedule_ptr ps, ps_insn_ptr ps_i, 3004 sbitmap must_precede, sbitmap must_follow) 3005 { 3006 ps_insn_ptr next_ps_i; 3007 ps_insn_ptr first_must_follow = NULL; 3008 ps_insn_ptr last_must_precede = NULL; 3009 ps_insn_ptr last_in_row = NULL; 3010 int row; 3011 3012 if (! ps_i) 3013 return false; 3014 3015 row = SMODULO (ps_i->cycle, ps->ii); 3016 3017 /* Find the first must follow and the last must precede 3018 and insert the node immediately after the must precede 3019 but make sure that it there is no must follow after it. */ 3020 for (next_ps_i = ps->rows[row]; 3021 next_ps_i; 3022 next_ps_i = next_ps_i->next_in_row) 3023 { 3024 if (must_follow 3025 && TEST_BIT (must_follow, next_ps_i->id) 3026 && ! first_must_follow) 3027 first_must_follow = next_ps_i; 3028 if (must_precede && TEST_BIT (must_precede, next_ps_i->id)) 3029 { 3030 /* If we have already met a node that must follow, then 3031 there is no possible column. */ 3032 if (first_must_follow) 3033 return false; 3034 else 3035 last_must_precede = next_ps_i; 3036 } 3037 /* The closing branch must be the last in the row. */ 3038 if (must_precede 3039 && TEST_BIT (must_precede, next_ps_i->id) 3040 && JUMP_P (ps_rtl_insn (ps, next_ps_i->id))) 3041 return false; 3042 3043 last_in_row = next_ps_i; 3044 } 3045 3046 /* The closing branch is scheduled as well. Make sure there is no 3047 dependent instruction after it as the branch should be the last 3048 instruction in the row. */ 3049 if (JUMP_P (ps_rtl_insn (ps, ps_i->id))) 3050 { 3051 if (first_must_follow) 3052 return false; 3053 if (last_in_row) 3054 { 3055 /* Make the branch the last in the row. New instructions 3056 will be inserted at the beginning of the row or after the 3057 last must_precede instruction thus the branch is guaranteed 3058 to remain the last instruction in the row. */ 3059 last_in_row->next_in_row = ps_i; 3060 ps_i->prev_in_row = last_in_row; 3061 ps_i->next_in_row = NULL; 3062 } 3063 else 3064 ps->rows[row] = ps_i; 3065 return true; 3066 } 3067 3068 /* Now insert the node after INSERT_AFTER_PSI. */ 3069 3070 if (! last_must_precede) 3071 { 3072 ps_i->next_in_row = ps->rows[row]; 3073 ps_i->prev_in_row = NULL; 3074 if (ps_i->next_in_row) 3075 ps_i->next_in_row->prev_in_row = ps_i; 3076 ps->rows[row] = ps_i; 3077 } 3078 else 3079 { 3080 ps_i->next_in_row = last_must_precede->next_in_row; 3081 last_must_precede->next_in_row = ps_i; 3082 ps_i->prev_in_row = last_must_precede; 3083 if (ps_i->next_in_row) 3084 ps_i->next_in_row->prev_in_row = ps_i; 3085 } 3086 3087 return true; 3088 } 3089 3090 /* Advances the PS_INSN one column in its current row; returns false 3091 in failure and true in success. Bit N is set in MUST_FOLLOW if 3092 the node with cuid N must be come after the node pointed to by 3093 PS_I when scheduled in the same cycle. */ 3094 static int 3095 ps_insn_advance_column (partial_schedule_ptr ps, ps_insn_ptr ps_i, 3096 sbitmap must_follow) 3097 { 3098 ps_insn_ptr prev, next; 3099 int row; 3100 3101 if (!ps || !ps_i) 3102 return false; 3103 3104 row = SMODULO (ps_i->cycle, ps->ii); 3105 3106 if (! ps_i->next_in_row) 3107 return false; 3108 3109 /* Check if next_in_row is dependent on ps_i, both having same sched 3110 times (typically ANTI_DEP). If so, ps_i cannot skip over it. */ 3111 if (must_follow && TEST_BIT (must_follow, ps_i->next_in_row->id)) 3112 return false; 3113 3114 /* Advance PS_I over its next_in_row in the doubly linked list. */ 3115 prev = ps_i->prev_in_row; 3116 next = ps_i->next_in_row; 3117 3118 if (ps_i == ps->rows[row]) 3119 ps->rows[row] = next; 3120 3121 ps_i->next_in_row = next->next_in_row; 3122 3123 if (next->next_in_row) 3124 next->next_in_row->prev_in_row = ps_i; 3125 3126 next->next_in_row = ps_i; 3127 ps_i->prev_in_row = next; 3128 3129 next->prev_in_row = prev; 3130 if (prev) 3131 prev->next_in_row = next; 3132 3133 return true; 3134 } 3135 3136 /* Inserts a DDG_NODE to the given partial schedule at the given cycle. 3137 Returns 0 if this is not possible and a PS_INSN otherwise. Bit N is 3138 set in MUST_PRECEDE/MUST_FOLLOW if the node with cuid N must be come 3139 before/after (respectively) the node pointed to by PS_I when scheduled 3140 in the same cycle. */ 3141 static ps_insn_ptr 3142 add_node_to_ps (partial_schedule_ptr ps, int id, int cycle, 3143 sbitmap must_precede, sbitmap must_follow) 3144 { 3145 ps_insn_ptr ps_i; 3146 int row = SMODULO (cycle, ps->ii); 3147 3148 if (ps->rows_length[row] >= issue_rate) 3149 return NULL; 3150 3151 ps_i = create_ps_insn (id, cycle); 3152 3153 /* Finds and inserts PS_I according to MUST_FOLLOW and 3154 MUST_PRECEDE. */ 3155 if (! ps_insn_find_column (ps, ps_i, must_precede, must_follow)) 3156 { 3157 free (ps_i); 3158 return NULL; 3159 } 3160 3161 ps->rows_length[row] += 1; 3162 return ps_i; 3163 } 3164 3165 /* Advance time one cycle. Assumes DFA is being used. */ 3166 static void 3167 advance_one_cycle (void) 3168 { 3169 if (targetm.sched.dfa_pre_cycle_insn) 3170 state_transition (curr_state, 3171 targetm.sched.dfa_pre_cycle_insn ()); 3172 3173 state_transition (curr_state, NULL); 3174 3175 if (targetm.sched.dfa_post_cycle_insn) 3176 state_transition (curr_state, 3177 targetm.sched.dfa_post_cycle_insn ()); 3178 } 3179 3180 3181 3182 /* Checks if PS has resource conflicts according to DFA, starting from 3183 FROM cycle to TO cycle; returns true if there are conflicts and false 3184 if there are no conflicts. Assumes DFA is being used. */ 3185 static int 3186 ps_has_conflicts (partial_schedule_ptr ps, int from, int to) 3187 { 3188 int cycle; 3189 3190 state_reset (curr_state); 3191 3192 for (cycle = from; cycle <= to; cycle++) 3193 { 3194 ps_insn_ptr crr_insn; 3195 /* Holds the remaining issue slots in the current row. */ 3196 int can_issue_more = issue_rate; 3197 3198 /* Walk through the DFA for the current row. */ 3199 for (crr_insn = ps->rows[SMODULO (cycle, ps->ii)]; 3200 crr_insn; 3201 crr_insn = crr_insn->next_in_row) 3202 { 3203 rtx insn = ps_rtl_insn (ps, crr_insn->id); 3204 3205 if (!NONDEBUG_INSN_P (insn)) 3206 continue; 3207 3208 /* Check if there is room for the current insn. */ 3209 if (!can_issue_more || state_dead_lock_p (curr_state)) 3210 return true; 3211 3212 /* Update the DFA state and return with failure if the DFA found 3213 resource conflicts. */ 3214 if (state_transition (curr_state, insn) >= 0) 3215 return true; 3216 3217 if (targetm.sched.variable_issue) 3218 can_issue_more = 3219 targetm.sched.variable_issue (sched_dump, sched_verbose, 3220 insn, can_issue_more); 3221 /* A naked CLOBBER or USE generates no instruction, so don't 3222 let them consume issue slots. */ 3223 else if (GET_CODE (PATTERN (insn)) != USE 3224 && GET_CODE (PATTERN (insn)) != CLOBBER) 3225 can_issue_more--; 3226 } 3227 3228 /* Advance the DFA to the next cycle. */ 3229 advance_one_cycle (); 3230 } 3231 return false; 3232 } 3233 3234 /* Checks if the given node causes resource conflicts when added to PS at 3235 cycle C. If not the node is added to PS and returned; otherwise zero 3236 is returned. Bit N is set in MUST_PRECEDE/MUST_FOLLOW if the node with 3237 cuid N must be come before/after (respectively) the node pointed to by 3238 PS_I when scheduled in the same cycle. */ 3239 ps_insn_ptr 3240 ps_add_node_check_conflicts (partial_schedule_ptr ps, int n, 3241 int c, sbitmap must_precede, 3242 sbitmap must_follow) 3243 { 3244 int has_conflicts = 0; 3245 ps_insn_ptr ps_i; 3246 3247 /* First add the node to the PS, if this succeeds check for 3248 conflicts, trying different issue slots in the same row. */ 3249 if (! (ps_i = add_node_to_ps (ps, n, c, must_precede, must_follow))) 3250 return NULL; /* Failed to insert the node at the given cycle. */ 3251 3252 has_conflicts = ps_has_conflicts (ps, c, c) 3253 || (ps->history > 0 3254 && ps_has_conflicts (ps, 3255 c - ps->history, 3256 c + ps->history)); 3257 3258 /* Try different issue slots to find one that the given node can be 3259 scheduled in without conflicts. */ 3260 while (has_conflicts) 3261 { 3262 if (! ps_insn_advance_column (ps, ps_i, must_follow)) 3263 break; 3264 has_conflicts = ps_has_conflicts (ps, c, c) 3265 || (ps->history > 0 3266 && ps_has_conflicts (ps, 3267 c - ps->history, 3268 c + ps->history)); 3269 } 3270 3271 if (has_conflicts) 3272 { 3273 remove_node_from_ps (ps, ps_i); 3274 return NULL; 3275 } 3276 3277 ps->min_cycle = MIN (ps->min_cycle, c); 3278 ps->max_cycle = MAX (ps->max_cycle, c); 3279 return ps_i; 3280 } 3281 3282 /* Calculate the stage count of the partial schedule PS. The calculation 3283 takes into account the rotation amount passed in ROTATION_AMOUNT. */ 3284 int 3285 calculate_stage_count (partial_schedule_ptr ps, int rotation_amount) 3286 { 3287 int new_min_cycle = PS_MIN_CYCLE (ps) - rotation_amount; 3288 int new_max_cycle = PS_MAX_CYCLE (ps) - rotation_amount; 3289 int stage_count = CALC_STAGE_COUNT (-1, new_min_cycle, ps->ii); 3290 3291 /* The calculation of stage count is done adding the number of stages 3292 before cycle zero and after cycle zero. */ 3293 stage_count += CALC_STAGE_COUNT (new_max_cycle, 0, ps->ii); 3294 3295 return stage_count; 3296 } 3297 3298 /* Rotate the rows of PS such that insns scheduled at time 3299 START_CYCLE will appear in row 0. Updates max/min_cycles. */ 3300 void 3301 rotate_partial_schedule (partial_schedule_ptr ps, int start_cycle) 3302 { 3303 int i, row, backward_rotates; 3304 int last_row = ps->ii - 1; 3305 3306 if (start_cycle == 0) 3307 return; 3308 3309 backward_rotates = SMODULO (start_cycle, ps->ii); 3310 3311 /* Revisit later and optimize this into a single loop. */ 3312 for (i = 0; i < backward_rotates; i++) 3313 { 3314 ps_insn_ptr first_row = ps->rows[0]; 3315 int first_row_length = ps->rows_length[0]; 3316 3317 for (row = 0; row < last_row; row++) 3318 { 3319 ps->rows[row] = ps->rows[row + 1]; 3320 ps->rows_length[row] = ps->rows_length[row + 1]; 3321 } 3322 3323 ps->rows[last_row] = first_row; 3324 ps->rows_length[last_row] = first_row_length; 3325 } 3326 3327 ps->max_cycle -= start_cycle; 3328 ps->min_cycle -= start_cycle; 3329 } 3330 3331 #endif /* INSN_SCHEDULING */ 3332 3333 static bool 3334 gate_handle_sms (void) 3335 { 3336 return (optimize > 0 && flag_modulo_sched); 3337 } 3338 3339 3340 /* Run instruction scheduler. */ 3341 /* Perform SMS module scheduling. */ 3342 static unsigned int 3343 rest_of_handle_sms (void) 3344 { 3345 #ifdef INSN_SCHEDULING 3346 basic_block bb; 3347 3348 /* Collect loop information to be used in SMS. */ 3349 cfg_layout_initialize (0); 3350 sms_schedule (); 3351 3352 /* Update the life information, because we add pseudos. */ 3353 max_regno = max_reg_num (); 3354 3355 /* Finalize layout changes. */ 3356 FOR_EACH_BB (bb) 3357 if (bb->next_bb != EXIT_BLOCK_PTR) 3358 bb->aux = bb->next_bb; 3359 free_dominance_info (CDI_DOMINATORS); 3360 cfg_layout_finalize (); 3361 #endif /* INSN_SCHEDULING */ 3362 return 0; 3363 } 3364 3365 struct rtl_opt_pass pass_sms = 3366 { 3367 { 3368 RTL_PASS, 3369 "sms", /* name */ 3370 gate_handle_sms, /* gate */ 3371 rest_of_handle_sms, /* execute */ 3372 NULL, /* sub */ 3373 NULL, /* next */ 3374 0, /* static_pass_number */ 3375 TV_SMS, /* tv_id */ 3376 0, /* properties_required */ 3377 0, /* properties_provided */ 3378 0, /* properties_destroyed */ 3379 0, /* todo_flags_start */ 3380 TODO_df_finish 3381 | TODO_verify_flow 3382 | TODO_verify_rtl_sharing 3383 | TODO_ggc_collect /* todo_flags_finish */ 3384 } 3385 }; 3386