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