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