OSDN Git Service

* dwarf2out.c (gen_compile_unit_die): Use DW_LANG_Go for Go.
[pf3gnuchains/gcc-fork.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 */