OSDN Git Service

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