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