1 /* DDG - Data Dependence Graph implementation. 2 Copyright (C) 2004-2013 Free Software Foundation, Inc. 3 Contributed by Ayal Zaks and Mustafa Hagog <zaks,mustafa@il.ibm.com> 4 5 This file is part of GCC. 6 7 GCC is free software; you can redistribute it and/or modify it under 8 the terms of the GNU General Public License as published by the Free 9 Software Foundation; either version 3, or (at your option) any later 10 version. 11 12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13 WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GCC; see the file COPYING3. If not see 19 <http://www.gnu.org/licenses/>. */ 20 21 22 #include "config.h" 23 #include "system.h" 24 #include "coretypes.h" 25 #include "tm.h" 26 #include "diagnostic-core.h" 27 #include "rtl.h" 28 #include "tm_p.h" 29 #include "hard-reg-set.h" 30 #include "regs.h" 31 #include "function.h" 32 #include "flags.h" 33 #include "insn-config.h" 34 #include "insn-attr.h" 35 #include "except.h" 36 #include "recog.h" 37 #include "sched-int.h" 38 #include "target.h" 39 #include "cfgloop.h" 40 #include "sbitmap.h" 41 #include "expr.h" 42 #include "bitmap.h" 43 #include "ddg.h" 44 45 #ifdef INSN_SCHEDULING 46 47 /* A flag indicating that a ddg edge belongs to an SCC or not. */ 48 enum edge_flag {NOT_IN_SCC = 0, IN_SCC}; 49 50 /* Forward declarations. */ 51 static void add_backarc_to_ddg (ddg_ptr, ddg_edge_ptr); 52 static void add_backarc_to_scc (ddg_scc_ptr, ddg_edge_ptr); 53 static void add_scc_to_ddg (ddg_all_sccs_ptr, ddg_scc_ptr); 54 static void create_ddg_dep_from_intra_loop_link (ddg_ptr, ddg_node_ptr, 55 ddg_node_ptr, dep_t); 56 static void create_ddg_dep_no_link (ddg_ptr, ddg_node_ptr, ddg_node_ptr, 57 dep_type, dep_data_type, int); 58 static ddg_edge_ptr create_ddg_edge (ddg_node_ptr, ddg_node_ptr, dep_type, 59 dep_data_type, int, int); 60 static void add_edge_to_ddg (ddg_ptr g, ddg_edge_ptr); 61 62 /* Auxiliary variable for mem_read_insn_p/mem_write_insn_p. */ 63 static bool mem_ref_p; 64 65 /* Auxiliary function for mem_read_insn_p. */ 66 static int 67 mark_mem_use (rtx *x, void *data ATTRIBUTE_UNUSED) 68 { 69 if (MEM_P (*x)) 70 mem_ref_p = true; 71 return 0; 72 } 73 74 /* Auxiliary function for mem_read_insn_p. */ 75 static void 76 mark_mem_use_1 (rtx *x, void *data) 77 { 78 for_each_rtx (x, mark_mem_use, data); 79 } 80 81 /* Returns nonzero if INSN reads from memory. */ 82 static bool 83 mem_read_insn_p (rtx insn) 84 { 85 mem_ref_p = false; 86 note_uses (&PATTERN (insn), mark_mem_use_1, NULL); 87 return mem_ref_p; 88 } 89 90 static void 91 mark_mem_store (rtx loc, const_rtx setter ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED) 92 { 93 if (MEM_P (loc)) 94 mem_ref_p = true; 95 } 96 97 /* Returns nonzero if INSN writes to memory. */ 98 static bool 99 mem_write_insn_p (rtx insn) 100 { 101 mem_ref_p = false; 102 note_stores (PATTERN (insn), mark_mem_store, NULL); 103 return mem_ref_p; 104 } 105 106 /* Returns nonzero if X has access to memory. */ 107 static bool 108 rtx_mem_access_p (rtx x) 109 { 110 int i, j; 111 const char *fmt; 112 enum rtx_code code; 113 114 if (x == 0) 115 return false; 116 117 if (MEM_P (x)) 118 return true; 119 120 code = GET_CODE (x); 121 fmt = GET_RTX_FORMAT (code); 122 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 123 { 124 if (fmt[i] == 'e') 125 { 126 if (rtx_mem_access_p (XEXP (x, i))) 127 return true; 128 } 129 else if (fmt[i] == 'E') 130 for (j = 0; j < XVECLEN (x, i); j++) 131 { 132 if (rtx_mem_access_p (XVECEXP (x, i, j))) 133 return true; 134 } 135 } 136 return false; 137 } 138 139 /* Returns nonzero if INSN reads to or writes from memory. */ 140 static bool 141 mem_access_insn_p (rtx insn) 142 { 143 return rtx_mem_access_p (PATTERN (insn)); 144 } 145 146 /* Return true if DEF_INSN contains address being auto-inc or auto-dec 147 which is used in USE_INSN. Otherwise return false. The result is 148 being used to decide whether to remove the edge between def_insn and 149 use_insn when -fmodulo-sched-allow-regmoves is set. This function 150 doesn't need to consider the specific address register; no reg_moves 151 will be allowed for any life range defined by def_insn and used 152 by use_insn, if use_insn uses an address register auto-inc'ed by 153 def_insn. */ 154 bool 155 autoinc_var_is_used_p (rtx def_insn, rtx use_insn) 156 { 157 rtx note; 158 159 for (note = REG_NOTES (def_insn); note; note = XEXP (note, 1)) 160 if (REG_NOTE_KIND (note) == REG_INC 161 && reg_referenced_p (XEXP (note, 0), PATTERN (use_insn))) 162 return true; 163 164 return false; 165 } 166 167 /* Return true if one of the definitions in INSN has MODE_CC. Otherwise 168 return false. */ 169 static bool 170 def_has_ccmode_p (rtx insn) 171 { 172 df_ref *def; 173 174 for (def = DF_INSN_DEFS (insn); *def; def++) 175 { 176 enum machine_mode mode = GET_MODE (DF_REF_REG (*def)); 177 178 if (GET_MODE_CLASS (mode) == MODE_CC) 179 return true; 180 } 181 182 return false; 183 } 184 185 /* Computes the dependence parameters (latency, distance etc.), creates 186 a ddg_edge and adds it to the given DDG. */ 187 static void 188 create_ddg_dep_from_intra_loop_link (ddg_ptr g, ddg_node_ptr src_node, 189 ddg_node_ptr dest_node, dep_t link) 190 { 191 ddg_edge_ptr e; 192 int latency, distance = 0; 193 dep_type t = TRUE_DEP; 194 dep_data_type dt = (mem_access_insn_p (src_node->insn) 195 && mem_access_insn_p (dest_node->insn) ? MEM_DEP 196 : REG_DEP); 197 gcc_assert (src_node->cuid < dest_node->cuid); 198 gcc_assert (link); 199 200 /* Note: REG_DEP_ANTI applies to MEM ANTI_DEP as well!! */ 201 if (DEP_TYPE (link) == REG_DEP_ANTI) 202 t = ANTI_DEP; 203 else if (DEP_TYPE (link) == REG_DEP_OUTPUT) 204 t = OUTPUT_DEP; 205 206 gcc_assert (!DEBUG_INSN_P (dest_node->insn) || t == ANTI_DEP); 207 gcc_assert (!DEBUG_INSN_P (src_node->insn) || t == ANTI_DEP); 208 209 /* We currently choose not to create certain anti-deps edges and 210 compensate for that by generating reg-moves based on the life-range 211 analysis. The anti-deps that will be deleted are the ones which 212 have true-deps edges in the opposite direction (in other words 213 the kernel has only one def of the relevant register). 214 If the address that is being auto-inc or auto-dec in DEST_NODE 215 is used in SRC_NODE then do not remove the edge to make sure 216 reg-moves will not be created for this address. 217 TODO: support the removal of all anti-deps edges, i.e. including those 218 whose register has multiple defs in the loop. */ 219 if (flag_modulo_sched_allow_regmoves 220 && (t == ANTI_DEP && dt == REG_DEP) 221 && !def_has_ccmode_p (dest_node->insn) 222 && !autoinc_var_is_used_p (dest_node->insn, src_node->insn)) 223 { 224 rtx set; 225 226 set = single_set (dest_node->insn); 227 /* TODO: Handle registers that REG_P is not true for them, i.e. 228 subregs and special registers. */ 229 if (set && REG_P (SET_DEST (set))) 230 { 231 int regno = REGNO (SET_DEST (set)); 232 df_ref first_def; 233 struct df_rd_bb_info *bb_info = DF_RD_BB_INFO (g->bb); 234 235 first_def = df_bb_regno_first_def_find (g->bb, regno); 236 gcc_assert (first_def); 237 238 if (bitmap_bit_p (&bb_info->gen, DF_REF_ID (first_def))) 239 return; 240 } 241 } 242 243 latency = dep_cost (link); 244 e = create_ddg_edge (src_node, dest_node, t, dt, latency, distance); 245 add_edge_to_ddg (g, e); 246 } 247 248 /* The same as the above function, but it doesn't require a link parameter. */ 249 static void 250 create_ddg_dep_no_link (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to, 251 dep_type d_t, dep_data_type d_dt, int distance) 252 { 253 ddg_edge_ptr e; 254 int l; 255 enum reg_note dep_kind; 256 struct _dep _dep, *dep = &_dep; 257 258 gcc_assert (!DEBUG_INSN_P (to->insn) || d_t == ANTI_DEP); 259 gcc_assert (!DEBUG_INSN_P (from->insn) || d_t == ANTI_DEP); 260 261 if (d_t == ANTI_DEP) 262 dep_kind = REG_DEP_ANTI; 263 else if (d_t == OUTPUT_DEP) 264 dep_kind = REG_DEP_OUTPUT; 265 else 266 { 267 gcc_assert (d_t == TRUE_DEP); 268 269 dep_kind = REG_DEP_TRUE; 270 } 271 272 init_dep (dep, from->insn, to->insn, dep_kind); 273 274 l = dep_cost (dep); 275 276 e = create_ddg_edge (from, to, d_t, d_dt, l, distance); 277 if (distance > 0) 278 add_backarc_to_ddg (g, e); 279 else 280 add_edge_to_ddg (g, e); 281 } 282 283 284 /* Given a downwards exposed register def LAST_DEF (which is the last 285 definition of that register in the bb), add inter-loop true dependences 286 to all its uses in the next iteration, an output dependence to the 287 first def of the same register (possibly itself) in the next iteration 288 and anti-dependences from its uses in the current iteration to the 289 first definition in the next iteration. */ 290 static void 291 add_cross_iteration_register_deps (ddg_ptr g, df_ref last_def) 292 { 293 int regno = DF_REF_REGNO (last_def); 294 struct df_link *r_use; 295 int has_use_in_bb_p = false; 296 rtx def_insn = DF_REF_INSN (last_def); 297 ddg_node_ptr last_def_node = get_node_of_insn (g, def_insn); 298 ddg_node_ptr use_node; 299 #ifdef ENABLE_CHECKING 300 struct df_rd_bb_info *bb_info = DF_RD_BB_INFO (g->bb); 301 #endif 302 df_ref first_def = df_bb_regno_first_def_find (g->bb, regno); 303 304 gcc_assert (last_def_node); 305 gcc_assert (first_def); 306 307 #ifdef ENABLE_CHECKING 308 if (DF_REF_ID (last_def) != DF_REF_ID (first_def)) 309 gcc_assert (!bitmap_bit_p (&bb_info->gen, 310 DF_REF_ID (first_def))); 311 #endif 312 313 /* Create inter-loop true dependences and anti dependences. */ 314 for (r_use = DF_REF_CHAIN (last_def); r_use != NULL; r_use = r_use->next) 315 { 316 rtx use_insn = DF_REF_INSN (r_use->ref); 317 318 if (BLOCK_FOR_INSN (use_insn) != g->bb) 319 continue; 320 321 /* ??? Do not handle uses with DF_REF_IN_NOTE notes. */ 322 use_node = get_node_of_insn (g, use_insn); 323 gcc_assert (use_node); 324 has_use_in_bb_p = true; 325 if (use_node->cuid <= last_def_node->cuid) 326 { 327 /* Add true deps from last_def to it's uses in the next 328 iteration. Any such upwards exposed use appears before 329 the last_def def. */ 330 create_ddg_dep_no_link (g, last_def_node, use_node, 331 DEBUG_INSN_P (use_insn) ? ANTI_DEP : TRUE_DEP, 332 REG_DEP, 1); 333 } 334 else if (!DEBUG_INSN_P (use_insn)) 335 { 336 /* Add anti deps from last_def's uses in the current iteration 337 to the first def in the next iteration. We do not add ANTI 338 dep when there is an intra-loop TRUE dep in the opposite 339 direction, but use regmoves to fix such disregarded ANTI 340 deps when broken. If the first_def reaches the USE then 341 there is such a dep. */ 342 ddg_node_ptr first_def_node = get_node_of_insn (g, 343 DF_REF_INSN (first_def)); 344 345 gcc_assert (first_def_node); 346 347 /* Always create the edge if the use node is a branch in 348 order to prevent the creation of reg-moves. 349 If the address that is being auto-inc or auto-dec in LAST_DEF 350 is used in USE_INSN then do not remove the edge to make sure 351 reg-moves will not be created for that address. */ 352 if (DF_REF_ID (last_def) != DF_REF_ID (first_def) 353 || !flag_modulo_sched_allow_regmoves 354 || JUMP_P (use_node->insn) 355 || autoinc_var_is_used_p (DF_REF_INSN (last_def), use_insn) 356 || def_has_ccmode_p (DF_REF_INSN (last_def))) 357 create_ddg_dep_no_link (g, use_node, first_def_node, ANTI_DEP, 358 REG_DEP, 1); 359 360 } 361 } 362 /* Create an inter-loop output dependence between LAST_DEF (which is the 363 last def in its block, being downwards exposed) and the first def in 364 its block. Avoid creating a self output dependence. Avoid creating 365 an output dependence if there is a dependence path between the two 366 defs starting with a true dependence to a use which can be in the 367 next iteration; followed by an anti dependence of that use to the 368 first def (i.e. if there is a use between the two defs.) */ 369 if (!has_use_in_bb_p) 370 { 371 ddg_node_ptr dest_node; 372 373 if (DF_REF_ID (last_def) == DF_REF_ID (first_def)) 374 return; 375 376 dest_node = get_node_of_insn (g, DF_REF_INSN (first_def)); 377 gcc_assert (dest_node); 378 create_ddg_dep_no_link (g, last_def_node, dest_node, 379 OUTPUT_DEP, REG_DEP, 1); 380 } 381 } 382 /* Build inter-loop dependencies, by looking at DF analysis backwards. */ 383 static void 384 build_inter_loop_deps (ddg_ptr g) 385 { 386 unsigned rd_num; 387 struct df_rd_bb_info *rd_bb_info; 388 bitmap_iterator bi; 389 390 rd_bb_info = DF_RD_BB_INFO (g->bb); 391 392 /* Find inter-loop register output, true and anti deps. */ 393 EXECUTE_IF_SET_IN_BITMAP (&rd_bb_info->gen, 0, rd_num, bi) 394 { 395 df_ref rd = DF_DEFS_GET (rd_num); 396 397 add_cross_iteration_register_deps (g, rd); 398 } 399 } 400 401 402 static int 403 walk_mems_2 (rtx *x, rtx mem) 404 { 405 if (MEM_P (*x)) 406 { 407 if (may_alias_p (*x, mem)) 408 return 1; 409 410 return -1; 411 } 412 return 0; 413 } 414 415 static int 416 walk_mems_1 (rtx *x, rtx *pat) 417 { 418 if (MEM_P (*x)) 419 { 420 /* Visit all MEMs in *PAT and check indepedence. */ 421 if (for_each_rtx (pat, (rtx_function) walk_mems_2, *x)) 422 /* Indicate that dependence was determined and stop traversal. */ 423 return 1; 424 425 return -1; 426 } 427 return 0; 428 } 429 430 /* Return 1 if two specified instructions have mem expr with conflict alias sets*/ 431 static int 432 insns_may_alias_p (rtx insn1, rtx insn2) 433 { 434 /* For each pair of MEMs in INSN1 and INSN2 check their independence. */ 435 return for_each_rtx (&PATTERN (insn1), (rtx_function) walk_mems_1, 436 &PATTERN (insn2)); 437 } 438 439 /* Given two nodes, analyze their RTL insns and add intra-loop mem deps 440 to ddg G. */ 441 static void 442 add_intra_loop_mem_dep (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to) 443 { 444 445 if ((from->cuid == to->cuid) 446 || !insns_may_alias_p (from->insn, to->insn)) 447 /* Do not create edge if memory references have disjoint alias sets 448 or 'to' and 'from' are the same instruction. */ 449 return; 450 451 if (mem_write_insn_p (from->insn)) 452 { 453 if (mem_read_insn_p (to->insn)) 454 create_ddg_dep_no_link (g, from, to, 455 DEBUG_INSN_P (to->insn) 456 ? ANTI_DEP : TRUE_DEP, MEM_DEP, 0); 457 else 458 create_ddg_dep_no_link (g, from, to, 459 DEBUG_INSN_P (to->insn) 460 ? ANTI_DEP : OUTPUT_DEP, MEM_DEP, 0); 461 } 462 else if (!mem_read_insn_p (to->insn)) 463 create_ddg_dep_no_link (g, from, to, ANTI_DEP, MEM_DEP, 0); 464 } 465 466 /* Given two nodes, analyze their RTL insns and add inter-loop mem deps 467 to ddg G. */ 468 static void 469 add_inter_loop_mem_dep (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to) 470 { 471 if (!insns_may_alias_p (from->insn, to->insn)) 472 /* Do not create edge if memory references have disjoint alias sets. */ 473 return; 474 475 if (mem_write_insn_p (from->insn)) 476 { 477 if (mem_read_insn_p (to->insn)) 478 create_ddg_dep_no_link (g, from, to, 479 DEBUG_INSN_P (to->insn) 480 ? ANTI_DEP : TRUE_DEP, MEM_DEP, 1); 481 else if (from->cuid != to->cuid) 482 create_ddg_dep_no_link (g, from, to, 483 DEBUG_INSN_P (to->insn) 484 ? ANTI_DEP : OUTPUT_DEP, MEM_DEP, 1); 485 } 486 else 487 { 488 if (mem_read_insn_p (to->insn)) 489 return; 490 else if (from->cuid != to->cuid) 491 { 492 create_ddg_dep_no_link (g, from, to, ANTI_DEP, MEM_DEP, 1); 493 if (DEBUG_INSN_P (from->insn) || DEBUG_INSN_P (to->insn)) 494 create_ddg_dep_no_link (g, to, from, ANTI_DEP, MEM_DEP, 1); 495 else 496 create_ddg_dep_no_link (g, to, from, TRUE_DEP, MEM_DEP, 1); 497 } 498 } 499 500 } 501 502 /* Perform intra-block Data Dependency analysis and connect the nodes in 503 the DDG. We assume the loop has a single basic block. */ 504 static void 505 build_intra_loop_deps (ddg_ptr g) 506 { 507 int i; 508 /* Hold the dependency analysis state during dependency calculations. */ 509 struct deps_desc tmp_deps; 510 rtx head, tail; 511 512 /* Build the dependence information, using the sched_analyze function. */ 513 init_deps_global (); 514 init_deps (&tmp_deps, false); 515 516 /* Do the intra-block data dependence analysis for the given block. */ 517 get_ebb_head_tail (g->bb, g->bb, &head, &tail); 518 sched_analyze (&tmp_deps, head, tail); 519 520 /* Build intra-loop data dependencies using the scheduler dependency 521 analysis. */ 522 for (i = 0; i < g->num_nodes; i++) 523 { 524 ddg_node_ptr dest_node = &g->nodes[i]; 525 sd_iterator_def sd_it; 526 dep_t dep; 527 528 if (! INSN_P (dest_node->insn)) 529 continue; 530 531 FOR_EACH_DEP (dest_node->insn, SD_LIST_BACK, sd_it, dep) 532 { 533 rtx src_insn = DEP_PRO (dep); 534 ddg_node_ptr src_node; 535 536 /* Don't add dependencies on debug insns to non-debug insns 537 to avoid codegen differences between -g and -g0. */ 538 if (DEBUG_INSN_P (src_insn) && !DEBUG_INSN_P (dest_node->insn)) 539 continue; 540 541 src_node = get_node_of_insn (g, src_insn); 542 543 if (!src_node) 544 continue; 545 546 create_ddg_dep_from_intra_loop_link (g, src_node, dest_node, dep); 547 } 548 549 /* If this insn modifies memory, add an edge to all insns that access 550 memory. */ 551 if (mem_access_insn_p (dest_node->insn)) 552 { 553 int j; 554 555 for (j = 0; j <= i; j++) 556 { 557 ddg_node_ptr j_node = &g->nodes[j]; 558 if (DEBUG_INSN_P (j_node->insn)) 559 continue; 560 if (mem_access_insn_p (j_node->insn)) 561 { 562 /* Don't bother calculating inter-loop dep if an intra-loop dep 563 already exists. */ 564 if (! bitmap_bit_p (dest_node->successors, j)) 565 add_inter_loop_mem_dep (g, dest_node, j_node); 566 /* If -fmodulo-sched-allow-regmoves 567 is set certain anti-dep edges are not created. 568 It might be that these anti-dep edges are on the 569 path from one memory instruction to another such that 570 removing these edges could cause a violation of the 571 memory dependencies. Thus we add intra edges between 572 every two memory instructions in this case. */ 573 if (flag_modulo_sched_allow_regmoves 574 && !bitmap_bit_p (dest_node->predecessors, j)) 575 add_intra_loop_mem_dep (g, j_node, dest_node); 576 } 577 } 578 } 579 } 580 581 /* Free the INSN_LISTs. */ 582 finish_deps_global (); 583 free_deps (&tmp_deps); 584 585 /* Free dependencies. */ 586 sched_free_deps (head, tail, false); 587 } 588 589 590 /* Given a basic block, create its DDG and return a pointer to a variable 591 of ddg type that represents it. 592 Initialize the ddg structure fields to the appropriate values. */ 593 ddg_ptr 594 create_ddg (basic_block bb, int closing_branch_deps) 595 { 596 ddg_ptr g; 597 rtx insn, first_note; 598 int i; 599 int num_nodes = 0; 600 601 g = (ddg_ptr) xcalloc (1, sizeof (struct ddg)); 602 603 g->bb = bb; 604 g->closing_branch_deps = closing_branch_deps; 605 606 /* Count the number of insns in the BB. */ 607 for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb)); 608 insn = NEXT_INSN (insn)) 609 { 610 if (! INSN_P (insn) || GET_CODE (PATTERN (insn)) == USE) 611 continue; 612 613 if (DEBUG_INSN_P (insn)) 614 g->num_debug++; 615 else 616 { 617 if (mem_read_insn_p (insn)) 618 g->num_loads++; 619 if (mem_write_insn_p (insn)) 620 g->num_stores++; 621 } 622 num_nodes++; 623 } 624 625 /* There is nothing to do for this BB. */ 626 if ((num_nodes - g->num_debug) <= 1) 627 { 628 free (g); 629 return NULL; 630 } 631 632 /* Allocate the nodes array, and initialize the nodes. */ 633 g->num_nodes = num_nodes; 634 g->nodes = (ddg_node_ptr) xcalloc (num_nodes, sizeof (struct ddg_node)); 635 g->closing_branch = NULL; 636 i = 0; 637 first_note = NULL_RTX; 638 for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb)); 639 insn = NEXT_INSN (insn)) 640 { 641 if (! INSN_P (insn)) 642 { 643 if (! first_note && NOTE_P (insn) 644 && NOTE_KIND (insn) != NOTE_INSN_BASIC_BLOCK) 645 first_note = insn; 646 continue; 647 } 648 if (JUMP_P (insn)) 649 { 650 gcc_assert (!g->closing_branch); 651 g->closing_branch = &g->nodes[i]; 652 } 653 else if (GET_CODE (PATTERN (insn)) == USE) 654 { 655 if (! first_note) 656 first_note = insn; 657 continue; 658 } 659 660 g->nodes[i].cuid = i; 661 g->nodes[i].successors = sbitmap_alloc (num_nodes); 662 bitmap_clear (g->nodes[i].successors); 663 g->nodes[i].predecessors = sbitmap_alloc (num_nodes); 664 bitmap_clear (g->nodes[i].predecessors); 665 g->nodes[i].first_note = (first_note ? first_note : insn); 666 g->nodes[i++].insn = insn; 667 first_note = NULL_RTX; 668 } 669 670 /* We must have found a branch in DDG. */ 671 gcc_assert (g->closing_branch); 672 673 674 /* Build the data dependency graph. */ 675 build_intra_loop_deps (g); 676 build_inter_loop_deps (g); 677 return g; 678 } 679 680 /* Free all the memory allocated for the DDG. */ 681 void 682 free_ddg (ddg_ptr g) 683 { 684 int i; 685 686 if (!g) 687 return; 688 689 for (i = 0; i < g->num_nodes; i++) 690 { 691 ddg_edge_ptr e = g->nodes[i].out; 692 693 while (e) 694 { 695 ddg_edge_ptr next = e->next_out; 696 697 free (e); 698 e = next; 699 } 700 sbitmap_free (g->nodes[i].successors); 701 sbitmap_free (g->nodes[i].predecessors); 702 } 703 if (g->num_backarcs > 0) 704 free (g->backarcs); 705 free (g->nodes); 706 free (g); 707 } 708 709 void 710 print_ddg_edge (FILE *file, ddg_edge_ptr e) 711 { 712 char dep_c; 713 714 switch (e->type) 715 { 716 case OUTPUT_DEP : 717 dep_c = 'O'; 718 break; 719 case ANTI_DEP : 720 dep_c = 'A'; 721 break; 722 default: 723 dep_c = 'T'; 724 } 725 726 fprintf (file, " [%d -(%c,%d,%d)-> %d] ", INSN_UID (e->src->insn), 727 dep_c, e->latency, e->distance, INSN_UID (e->dest->insn)); 728 } 729 730 /* Print the DDG nodes with there in/out edges to the dump file. */ 731 void 732 print_ddg (FILE *file, ddg_ptr g) 733 { 734 int i; 735 736 for (i = 0; i < g->num_nodes; i++) 737 { 738 ddg_edge_ptr e; 739 740 fprintf (file, "Node num: %d\n", g->nodes[i].cuid); 741 print_rtl_single (file, g->nodes[i].insn); 742 fprintf (file, "OUT ARCS: "); 743 for (e = g->nodes[i].out; e; e = e->next_out) 744 print_ddg_edge (file, e); 745 746 fprintf (file, "\nIN ARCS: "); 747 for (e = g->nodes[i].in; e; e = e->next_in) 748 print_ddg_edge (file, e); 749 750 fprintf (file, "\n"); 751 } 752 } 753 754 /* Print the given DDG in VCG format. */ 755 DEBUG_FUNCTION void 756 vcg_print_ddg (FILE *file, ddg_ptr g) 757 { 758 int src_cuid; 759 760 fprintf (file, "graph: {\n"); 761 for (src_cuid = 0; src_cuid < g->num_nodes; src_cuid++) 762 { 763 ddg_edge_ptr e; 764 int src_uid = INSN_UID (g->nodes[src_cuid].insn); 765 766 fprintf (file, "node: {title: \"%d_%d\" info1: \"", src_cuid, src_uid); 767 print_rtl_single (file, g->nodes[src_cuid].insn); 768 fprintf (file, "\"}\n"); 769 for (e = g->nodes[src_cuid].out; e; e = e->next_out) 770 { 771 int dst_uid = INSN_UID (e->dest->insn); 772 int dst_cuid = e->dest->cuid; 773 774 /* Give the backarcs a different color. */ 775 if (e->distance > 0) 776 fprintf (file, "backedge: {color: red "); 777 else 778 fprintf (file, "edge: { "); 779 780 fprintf (file, "sourcename: \"%d_%d\" ", src_cuid, src_uid); 781 fprintf (file, "targetname: \"%d_%d\" ", dst_cuid, dst_uid); 782 fprintf (file, "label: \"%d_%d\"}\n", e->latency, e->distance); 783 } 784 } 785 fprintf (file, "}\n"); 786 } 787 788 /* Dump the sccs in SCCS. */ 789 void 790 print_sccs (FILE *file, ddg_all_sccs_ptr sccs, ddg_ptr g) 791 { 792 unsigned int u = 0; 793 sbitmap_iterator sbi; 794 int i; 795 796 if (!file) 797 return; 798 799 fprintf (file, "\n;; Number of SCC nodes - %d\n", sccs->num_sccs); 800 for (i = 0; i < sccs->num_sccs; i++) 801 { 802 fprintf (file, "SCC number: %d\n", i); 803 EXECUTE_IF_SET_IN_BITMAP (sccs->sccs[i]->nodes, 0, u, sbi) 804 { 805 fprintf (file, "insn num %d\n", u); 806 print_rtl_single (file, g->nodes[u].insn); 807 } 808 } 809 fprintf (file, "\n"); 810 } 811 812 /* Create an edge and initialize it with given values. */ 813 static ddg_edge_ptr 814 create_ddg_edge (ddg_node_ptr src, ddg_node_ptr dest, 815 dep_type t, dep_data_type dt, int l, int d) 816 { 817 ddg_edge_ptr e = (ddg_edge_ptr) xmalloc (sizeof (struct ddg_edge)); 818 819 e->src = src; 820 e->dest = dest; 821 e->type = t; 822 e->data_type = dt; 823 e->latency = l; 824 e->distance = d; 825 e->next_in = e->next_out = NULL; 826 e->aux.info = 0; 827 return e; 828 } 829 830 /* Add the given edge to the in/out linked lists of the DDG nodes. */ 831 static void 832 add_edge_to_ddg (ddg_ptr g ATTRIBUTE_UNUSED, ddg_edge_ptr e) 833 { 834 ddg_node_ptr src = e->src; 835 ddg_node_ptr dest = e->dest; 836 837 /* Should have allocated the sbitmaps. */ 838 gcc_assert (src->successors && dest->predecessors); 839 840 bitmap_set_bit (src->successors, dest->cuid); 841 bitmap_set_bit (dest->predecessors, src->cuid); 842 e->next_in = dest->in; 843 dest->in = e; 844 e->next_out = src->out; 845 src->out = e; 846 } 847 848 849 850 /* Algorithm for computing the recurrence_length of an scc. We assume at 851 for now that cycles in the data dependence graph contain a single backarc. 852 This simplifies the algorithm, and can be generalized later. */ 853 static void 854 set_recurrence_length (ddg_scc_ptr scc, ddg_ptr g) 855 { 856 int j; 857 int result = -1; 858 859 for (j = 0; j < scc->num_backarcs; j++) 860 { 861 ddg_edge_ptr backarc = scc->backarcs[j]; 862 int length; 863 int distance = backarc->distance; 864 ddg_node_ptr src = backarc->dest; 865 ddg_node_ptr dest = backarc->src; 866 867 length = longest_simple_path (g, src->cuid, dest->cuid, scc->nodes); 868 if (length < 0 ) 869 { 870 /* fprintf (stderr, "Backarc not on simple cycle in SCC.\n"); */ 871 continue; 872 } 873 length += backarc->latency; 874 result = MAX (result, (length / distance)); 875 } 876 scc->recurrence_length = result; 877 } 878 879 /* Create a new SCC given the set of its nodes. Compute its recurrence_length 880 and mark edges that belong to this scc as IN_SCC. */ 881 static ddg_scc_ptr 882 create_scc (ddg_ptr g, sbitmap nodes) 883 { 884 ddg_scc_ptr scc; 885 unsigned int u = 0; 886 sbitmap_iterator sbi; 887 888 scc = (ddg_scc_ptr) xmalloc (sizeof (struct ddg_scc)); 889 scc->backarcs = NULL; 890 scc->num_backarcs = 0; 891 scc->nodes = sbitmap_alloc (g->num_nodes); 892 bitmap_copy (scc->nodes, nodes); 893 894 /* Mark the backarcs that belong to this SCC. */ 895 EXECUTE_IF_SET_IN_BITMAP (nodes, 0, u, sbi) 896 { 897 ddg_edge_ptr e; 898 ddg_node_ptr n = &g->nodes[u]; 899 900 for (e = n->out; e; e = e->next_out) 901 if (bitmap_bit_p (nodes, e->dest->cuid)) 902 { 903 e->aux.count = IN_SCC; 904 if (e->distance > 0) 905 add_backarc_to_scc (scc, e); 906 } 907 } 908 909 set_recurrence_length (scc, g); 910 return scc; 911 } 912 913 /* Cleans the memory allocation of a given SCC. */ 914 static void 915 free_scc (ddg_scc_ptr scc) 916 { 917 if (!scc) 918 return; 919 920 sbitmap_free (scc->nodes); 921 if (scc->num_backarcs > 0) 922 free (scc->backarcs); 923 free (scc); 924 } 925 926 927 /* Add a given edge known to be a backarc to the given DDG. */ 928 static void 929 add_backarc_to_ddg (ddg_ptr g, ddg_edge_ptr e) 930 { 931 int size = (g->num_backarcs + 1) * sizeof (ddg_edge_ptr); 932 933 add_edge_to_ddg (g, e); 934 g->backarcs = (ddg_edge_ptr *) xrealloc (g->backarcs, size); 935 g->backarcs[g->num_backarcs++] = e; 936 } 937 938 /* Add backarc to an SCC. */ 939 static void 940 add_backarc_to_scc (ddg_scc_ptr scc, ddg_edge_ptr e) 941 { 942 int size = (scc->num_backarcs + 1) * sizeof (ddg_edge_ptr); 943 944 scc->backarcs = (ddg_edge_ptr *) xrealloc (scc->backarcs, size); 945 scc->backarcs[scc->num_backarcs++] = e; 946 } 947 948 /* Add the given SCC to the DDG. */ 949 static void 950 add_scc_to_ddg (ddg_all_sccs_ptr g, ddg_scc_ptr scc) 951 { 952 int size = (g->num_sccs + 1) * sizeof (ddg_scc_ptr); 953 954 g->sccs = (ddg_scc_ptr *) xrealloc (g->sccs, size); 955 g->sccs[g->num_sccs++] = scc; 956 } 957 958 /* Given the instruction INSN return the node that represents it. */ 959 ddg_node_ptr 960 get_node_of_insn (ddg_ptr g, rtx insn) 961 { 962 int i; 963 964 for (i = 0; i < g->num_nodes; i++) 965 if (insn == g->nodes[i].insn) 966 return &g->nodes[i]; 967 return NULL; 968 } 969 970 /* Given a set OPS of nodes in the DDG, find the set of their successors 971 which are not in OPS, and set their bits in SUCC. Bits corresponding to 972 OPS are cleared from SUCC. Leaves the other bits in SUCC unchanged. */ 973 void 974 find_successors (sbitmap succ, ddg_ptr g, sbitmap ops) 975 { 976 unsigned int i = 0; 977 sbitmap_iterator sbi; 978 979 EXECUTE_IF_SET_IN_BITMAP (ops, 0, i, sbi) 980 { 981 const sbitmap node_succ = NODE_SUCCESSORS (&g->nodes[i]); 982 bitmap_ior (succ, succ, node_succ); 983 }; 984 985 /* We want those that are not in ops. */ 986 bitmap_and_compl (succ, succ, ops); 987 } 988 989 /* Given a set OPS of nodes in the DDG, find the set of their predecessors 990 which are not in OPS, and set their bits in PREDS. Bits corresponding to 991 OPS are cleared from PREDS. Leaves the other bits in PREDS unchanged. */ 992 void 993 find_predecessors (sbitmap preds, ddg_ptr g, sbitmap ops) 994 { 995 unsigned int i = 0; 996 sbitmap_iterator sbi; 997 998 EXECUTE_IF_SET_IN_BITMAP (ops, 0, i, sbi) 999 { 1000 const sbitmap node_preds = NODE_PREDECESSORS (&g->nodes[i]); 1001 bitmap_ior (preds, preds, node_preds); 1002 }; 1003 1004 /* We want those that are not in ops. */ 1005 bitmap_and_compl (preds, preds, ops); 1006 } 1007 1008 1009 /* Compare function to be passed to qsort to order the backarcs in descending 1010 recMII order. */ 1011 static int 1012 compare_sccs (const void *s1, const void *s2) 1013 { 1014 const int rec_l1 = (*(const ddg_scc_ptr *)s1)->recurrence_length; 1015 const int rec_l2 = (*(const ddg_scc_ptr *)s2)->recurrence_length; 1016 return ((rec_l2 > rec_l1) - (rec_l2 < rec_l1)); 1017 1018 } 1019 1020 /* Order the backarcs in descending recMII order using compare_sccs. */ 1021 static void 1022 order_sccs (ddg_all_sccs_ptr g) 1023 { 1024 qsort (g->sccs, g->num_sccs, sizeof (ddg_scc_ptr), 1025 (int (*) (const void *, const void *)) compare_sccs); 1026 } 1027 1028 #ifdef ENABLE_CHECKING 1029 /* Check that every node in SCCS belongs to exactly one strongly connected 1030 component and that no element of SCCS is empty. */ 1031 static void 1032 check_sccs (ddg_all_sccs_ptr sccs, int num_nodes) 1033 { 1034 int i = 0; 1035 sbitmap tmp = sbitmap_alloc (num_nodes); 1036 1037 bitmap_clear (tmp); 1038 for (i = 0; i < sccs->num_sccs; i++) 1039 { 1040 gcc_assert (!bitmap_empty_p (sccs->sccs[i]->nodes)); 1041 /* Verify that every node in sccs is in exactly one strongly 1042 connected component. */ 1043 gcc_assert (!bitmap_intersect_p (tmp, sccs->sccs[i]->nodes)); 1044 bitmap_ior (tmp, tmp, sccs->sccs[i]->nodes); 1045 } 1046 sbitmap_free (tmp); 1047 } 1048 #endif 1049 1050 /* Perform the Strongly Connected Components decomposing algorithm on the 1051 DDG and return DDG_ALL_SCCS structure that contains them. */ 1052 ddg_all_sccs_ptr 1053 create_ddg_all_sccs (ddg_ptr g) 1054 { 1055 int i; 1056 int num_nodes = g->num_nodes; 1057 sbitmap from = sbitmap_alloc (num_nodes); 1058 sbitmap to = sbitmap_alloc (num_nodes); 1059 sbitmap scc_nodes = sbitmap_alloc (num_nodes); 1060 ddg_all_sccs_ptr sccs = (ddg_all_sccs_ptr) 1061 xmalloc (sizeof (struct ddg_all_sccs)); 1062 1063 sccs->ddg = g; 1064 sccs->sccs = NULL; 1065 sccs->num_sccs = 0; 1066 1067 for (i = 0; i < g->num_backarcs; i++) 1068 { 1069 ddg_scc_ptr scc; 1070 ddg_edge_ptr backarc = g->backarcs[i]; 1071 ddg_node_ptr src = backarc->src; 1072 ddg_node_ptr dest = backarc->dest; 1073 1074 /* If the backarc already belongs to an SCC, continue. */ 1075 if (backarc->aux.count == IN_SCC) 1076 continue; 1077 1078 bitmap_clear (scc_nodes); 1079 bitmap_clear (from); 1080 bitmap_clear (to); 1081 bitmap_set_bit (from, dest->cuid); 1082 bitmap_set_bit (to, src->cuid); 1083 1084 if (find_nodes_on_paths (scc_nodes, g, from, to)) 1085 { 1086 scc = create_scc (g, scc_nodes); 1087 add_scc_to_ddg (sccs, scc); 1088 } 1089 } 1090 order_sccs (sccs); 1091 sbitmap_free (from); 1092 sbitmap_free (to); 1093 sbitmap_free (scc_nodes); 1094 #ifdef ENABLE_CHECKING 1095 check_sccs (sccs, num_nodes); 1096 #endif 1097 return sccs; 1098 } 1099 1100 /* Frees the memory allocated for all SCCs of the DDG, but keeps the DDG. */ 1101 void 1102 free_ddg_all_sccs (ddg_all_sccs_ptr all_sccs) 1103 { 1104 int i; 1105 1106 if (!all_sccs) 1107 return; 1108 1109 for (i = 0; i < all_sccs->num_sccs; i++) 1110 free_scc (all_sccs->sccs[i]); 1111 1112 free (all_sccs->sccs); 1113 free (all_sccs); 1114 } 1115 1116 1117 /* Given FROM - a bitmap of source nodes - and TO - a bitmap of destination 1118 nodes - find all nodes that lie on paths from FROM to TO (not excluding 1119 nodes from FROM and TO). Return nonzero if nodes exist. */ 1120 int 1121 find_nodes_on_paths (sbitmap result, ddg_ptr g, sbitmap from, sbitmap to) 1122 { 1123 int answer; 1124 int change; 1125 unsigned int u = 0; 1126 int num_nodes = g->num_nodes; 1127 sbitmap_iterator sbi; 1128 1129 sbitmap workset = sbitmap_alloc (num_nodes); 1130 sbitmap reachable_from = sbitmap_alloc (num_nodes); 1131 sbitmap reach_to = sbitmap_alloc (num_nodes); 1132 sbitmap tmp = sbitmap_alloc (num_nodes); 1133 1134 bitmap_copy (reachable_from, from); 1135 bitmap_copy (tmp, from); 1136 1137 change = 1; 1138 while (change) 1139 { 1140 change = 0; 1141 bitmap_copy (workset, tmp); 1142 bitmap_clear (tmp); 1143 EXECUTE_IF_SET_IN_BITMAP (workset, 0, u, sbi) 1144 { 1145 ddg_edge_ptr e; 1146 ddg_node_ptr u_node = &g->nodes[u]; 1147 1148 for (e = u_node->out; e != (ddg_edge_ptr) 0; e = e->next_out) 1149 { 1150 ddg_node_ptr v_node = e->dest; 1151 int v = v_node->cuid; 1152 1153 if (!bitmap_bit_p (reachable_from, v)) 1154 { 1155 bitmap_set_bit (reachable_from, v); 1156 bitmap_set_bit (tmp, v); 1157 change = 1; 1158 } 1159 } 1160 } 1161 } 1162 1163 bitmap_copy (reach_to, to); 1164 bitmap_copy (tmp, to); 1165 1166 change = 1; 1167 while (change) 1168 { 1169 change = 0; 1170 bitmap_copy (workset, tmp); 1171 bitmap_clear (tmp); 1172 EXECUTE_IF_SET_IN_BITMAP (workset, 0, u, sbi) 1173 { 1174 ddg_edge_ptr e; 1175 ddg_node_ptr u_node = &g->nodes[u]; 1176 1177 for (e = u_node->in; e != (ddg_edge_ptr) 0; e = e->next_in) 1178 { 1179 ddg_node_ptr v_node = e->src; 1180 int v = v_node->cuid; 1181 1182 if (!bitmap_bit_p (reach_to, v)) 1183 { 1184 bitmap_set_bit (reach_to, v); 1185 bitmap_set_bit (tmp, v); 1186 change = 1; 1187 } 1188 } 1189 } 1190 } 1191 1192 answer = bitmap_and (result, reachable_from, reach_to); 1193 sbitmap_free (workset); 1194 sbitmap_free (reachable_from); 1195 sbitmap_free (reach_to); 1196 sbitmap_free (tmp); 1197 return answer; 1198 } 1199 1200 1201 /* Updates the counts of U_NODE's successors (that belong to NODES) to be 1202 at-least as large as the count of U_NODE plus the latency between them. 1203 Sets a bit in TMP for each successor whose count was changed (increased). 1204 Returns nonzero if any count was changed. */ 1205 static int 1206 update_dist_to_successors (ddg_node_ptr u_node, sbitmap nodes, sbitmap tmp) 1207 { 1208 ddg_edge_ptr e; 1209 int result = 0; 1210 1211 for (e = u_node->out; e; e = e->next_out) 1212 { 1213 ddg_node_ptr v_node = e->dest; 1214 int v = v_node->cuid; 1215 1216 if (bitmap_bit_p (nodes, v) 1217 && (e->distance == 0) 1218 && (v_node->aux.count < u_node->aux.count + e->latency)) 1219 { 1220 v_node->aux.count = u_node->aux.count + e->latency; 1221 bitmap_set_bit (tmp, v); 1222 result = 1; 1223 } 1224 } 1225 return result; 1226 } 1227 1228 1229 /* Find the length of a longest path from SRC to DEST in G, 1230 going only through NODES, and disregarding backarcs. */ 1231 int 1232 longest_simple_path (struct ddg * g, int src, int dest, sbitmap nodes) 1233 { 1234 int i; 1235 unsigned int u = 0; 1236 int change = 1; 1237 int result; 1238 int num_nodes = g->num_nodes; 1239 sbitmap workset = sbitmap_alloc (num_nodes); 1240 sbitmap tmp = sbitmap_alloc (num_nodes); 1241 1242 1243 /* Data will hold the distance of the longest path found so far from 1244 src to each node. Initialize to -1 = less than minimum. */ 1245 for (i = 0; i < g->num_nodes; i++) 1246 g->nodes[i].aux.count = -1; 1247 g->nodes[src].aux.count = 0; 1248 1249 bitmap_clear (tmp); 1250 bitmap_set_bit (tmp, src); 1251 1252 while (change) 1253 { 1254 sbitmap_iterator sbi; 1255 1256 change = 0; 1257 bitmap_copy (workset, tmp); 1258 bitmap_clear (tmp); 1259 EXECUTE_IF_SET_IN_BITMAP (workset, 0, u, sbi) 1260 { 1261 ddg_node_ptr u_node = &g->nodes[u]; 1262 1263 change |= update_dist_to_successors (u_node, nodes, tmp); 1264 } 1265 } 1266 result = g->nodes[dest].aux.count; 1267 sbitmap_free (workset); 1268 sbitmap_free (tmp); 1269 return result; 1270 } 1271 1272 #endif /* INSN_SCHEDULING */ 1273