OSDN Git Service

PR fortran/31612
[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       print_rtl_single (file, g->nodes[i].insn);
572       fprintf (file, "OUT ARCS: ");
573       for (e = g->nodes[i].out; e; e = e->next_out)
574         print_ddg_edge (file, e);
575
576       fprintf (file, "\nIN ARCS: ");
577       for (e = g->nodes[i].in; e; e = e->next_in)
578         print_ddg_edge (file, e);
579
580       fprintf (file, "\n");
581     }
582 }
583
584 /* Print the given DDG in VCG format.  */
585 void
586 vcg_print_ddg (FILE *file, ddg_ptr g)
587 {
588   int src_cuid;
589
590   fprintf (file, "graph: {\n");
591   for (src_cuid = 0; src_cuid < g->num_nodes; src_cuid++)
592     {
593       ddg_edge_ptr e;
594       int src_uid = INSN_UID (g->nodes[src_cuid].insn);
595
596       fprintf (file, "node: {title: \"%d_%d\" info1: \"", src_cuid, src_uid);
597       print_rtl_single (file, g->nodes[src_cuid].insn);
598       fprintf (file, "\"}\n");
599       for (e = g->nodes[src_cuid].out; e; e = e->next_out)
600         {
601           int dst_uid = INSN_UID (e->dest->insn);
602           int dst_cuid = e->dest->cuid;
603
604           /* Give the backarcs a different color.  */
605           if (e->distance > 0)
606             fprintf (file, "backedge: {color: red ");
607           else
608             fprintf (file, "edge: { ");
609
610           fprintf (file, "sourcename: \"%d_%d\" ", src_cuid, src_uid);
611           fprintf (file, "targetname: \"%d_%d\" ", dst_cuid, dst_uid);
612           fprintf (file, "label: \"%d_%d\"}\n", e->latency, e->distance);
613         }
614     }
615   fprintf (file, "}\n");
616 }
617
618 /* Dump the sccs in SCCS.  */
619 void
620 print_sccs (FILE *file, ddg_all_sccs_ptr sccs, ddg_ptr g)
621 {
622   unsigned int u = 0;
623   sbitmap_iterator sbi;
624   int i;
625
626   if (!file)
627     return;
628
629   fprintf (file, "\n;; Number of SCC nodes - %d\n", sccs->num_sccs);
630   for (i = 0; i < sccs->num_sccs; i++)
631     {
632       fprintf (file, "SCC number: %d\n", i);
633       EXECUTE_IF_SET_IN_SBITMAP (sccs->sccs[i]->nodes, 0, u, sbi)
634       {
635         fprintf (file, "insn num %d\n", u);
636         print_rtl_single (file, g->nodes[u].insn);
637       }
638     }
639   fprintf (file, "\n");
640 }
641
642 /* Create an edge and initialize it with given values.  */
643 static ddg_edge_ptr
644 create_ddg_edge (ddg_node_ptr src, ddg_node_ptr dest,
645                  dep_type t, dep_data_type dt, int l, int d)
646 {
647   ddg_edge_ptr e = (ddg_edge_ptr) xmalloc (sizeof (struct ddg_edge));
648
649   e->src = src;
650   e->dest = dest;
651   e->type = t;
652   e->data_type = dt;
653   e->latency = l;
654   e->distance = d;
655   e->next_in = e->next_out = NULL;
656   e->aux.info = 0;
657   return e;
658 }
659
660 /* Add the given edge to the in/out linked lists of the DDG nodes.  */
661 static void
662 add_edge_to_ddg (ddg_ptr g ATTRIBUTE_UNUSED, ddg_edge_ptr e)
663 {
664   ddg_node_ptr src = e->src;
665   ddg_node_ptr dest = e->dest;
666
667   /* Should have allocated the sbitmaps.  */
668   gcc_assert (src->successors && dest->predecessors);
669
670   SET_BIT (src->successors, dest->cuid);
671   SET_BIT (dest->predecessors, src->cuid);
672   e->next_in = dest->in;
673   dest->in = e;
674   e->next_out = src->out;
675   src->out = e;
676 }
677
678
679 \f
680 /* Algorithm for computing the recurrence_length of an scc.  We assume at
681    for now that cycles in the data dependence graph contain a single backarc.
682    This simplifies the algorithm, and can be generalized later.  */
683 static void
684 set_recurrence_length (ddg_scc_ptr scc, ddg_ptr g)
685 {
686   int j;
687   int result = -1;
688
689   for (j = 0; j < scc->num_backarcs; j++)
690     {
691       ddg_edge_ptr backarc = scc->backarcs[j];
692       int length;
693       int distance = backarc->distance;
694       ddg_node_ptr src = backarc->dest;
695       ddg_node_ptr dest = backarc->src;
696
697       length = longest_simple_path (g, src->cuid, dest->cuid, scc->nodes);
698       if (length < 0 )
699         {
700           /* fprintf (stderr, "Backarc not on simple cycle in SCC.\n"); */
701           continue;
702         }
703       length += backarc->latency;
704       result = MAX (result, (length / distance));
705     }
706   scc->recurrence_length = result;
707 }
708
709 /* Create a new SCC given the set of its nodes.  Compute its recurrence_length
710    and mark edges that belong to this scc as IN_SCC.  */
711 static ddg_scc_ptr
712 create_scc (ddg_ptr g, sbitmap nodes)
713 {
714   ddg_scc_ptr scc;
715   unsigned int u = 0;
716   sbitmap_iterator sbi;
717
718   scc = (ddg_scc_ptr) xmalloc (sizeof (struct ddg_scc));
719   scc->backarcs = NULL;
720   scc->num_backarcs = 0;
721   scc->nodes = sbitmap_alloc (g->num_nodes);
722   sbitmap_copy (scc->nodes, nodes);
723
724   /* Mark the backarcs that belong to this SCC.  */
725   EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi)
726     {
727       ddg_edge_ptr e;
728       ddg_node_ptr n = &g->nodes[u];
729
730       for (e = n->out; e; e = e->next_out)
731         if (TEST_BIT (nodes, e->dest->cuid))
732           {
733             e->aux.count = IN_SCC;
734             if (e->distance > 0)
735               add_backarc_to_scc (scc, e);
736           }
737     }
738
739   set_recurrence_length (scc, g);
740   return scc;
741 }
742
743 /* Cleans the memory allocation of a given SCC.  */
744 static void
745 free_scc (ddg_scc_ptr scc)
746 {
747   if (!scc)
748     return;
749
750   sbitmap_free (scc->nodes);
751   if (scc->num_backarcs > 0)
752     free (scc->backarcs);
753   free (scc);
754 }
755
756
757 /* Add a given edge known to be a backarc to the given DDG.  */
758 static void
759 add_backarc_to_ddg (ddg_ptr g, ddg_edge_ptr e)
760 {
761   int size = (g->num_backarcs + 1) * sizeof (ddg_edge_ptr);
762
763   add_edge_to_ddg (g, e);
764   g->backarcs = (ddg_edge_ptr *) xrealloc (g->backarcs, size);
765   g->backarcs[g->num_backarcs++] = e;
766 }
767
768 /* Add backarc to an SCC.  */
769 static void
770 add_backarc_to_scc (ddg_scc_ptr scc, ddg_edge_ptr e)
771 {
772   int size = (scc->num_backarcs + 1) * sizeof (ddg_edge_ptr);
773
774   scc->backarcs = (ddg_edge_ptr *) xrealloc (scc->backarcs, size);
775   scc->backarcs[scc->num_backarcs++] = e;
776 }
777
778 /* Add the given SCC to the DDG.  */
779 static void
780 add_scc_to_ddg (ddg_all_sccs_ptr g, ddg_scc_ptr scc)
781 {
782   int size = (g->num_sccs + 1) * sizeof (ddg_scc_ptr);
783
784   g->sccs = (ddg_scc_ptr *) xrealloc (g->sccs, size);
785   g->sccs[g->num_sccs++] = scc;
786 }
787
788 /* Given the instruction INSN return the node that represents it.  */
789 ddg_node_ptr
790 get_node_of_insn (ddg_ptr g, rtx insn)
791 {
792   int i;
793
794   for (i = 0; i < g->num_nodes; i++)
795     if (insn == g->nodes[i].insn)
796       return &g->nodes[i];
797   return NULL;
798 }
799
800 /* Given a set OPS of nodes in the DDG, find the set of their successors
801    which are not in OPS, and set their bits in SUCC.  Bits corresponding to
802    OPS are cleared from SUCC.  Leaves the other bits in SUCC unchanged.  */
803 void
804 find_successors (sbitmap succ, ddg_ptr g, sbitmap ops)
805 {
806   unsigned int i = 0;
807   sbitmap_iterator sbi;
808
809   EXECUTE_IF_SET_IN_SBITMAP (ops, 0, i, sbi)
810     {
811       const sbitmap node_succ = NODE_SUCCESSORS (&g->nodes[i]);
812       sbitmap_a_or_b (succ, succ, node_succ);
813     };
814
815   /* We want those that are not in ops.  */
816   sbitmap_difference (succ, succ, ops);
817 }
818
819 /* Given a set OPS of nodes in the DDG, find the set of their predecessors
820    which are not in OPS, and set their bits in PREDS.  Bits corresponding to
821    OPS are cleared from PREDS.  Leaves the other bits in PREDS unchanged.  */
822 void
823 find_predecessors (sbitmap preds, ddg_ptr g, sbitmap ops)
824 {
825   unsigned int i = 0;
826   sbitmap_iterator sbi;
827
828   EXECUTE_IF_SET_IN_SBITMAP (ops, 0, i, sbi)
829     {
830       const sbitmap node_preds = NODE_PREDECESSORS (&g->nodes[i]);
831       sbitmap_a_or_b (preds, preds, node_preds);
832     };
833
834   /* We want those that are not in ops.  */
835   sbitmap_difference (preds, preds, ops);
836 }
837
838
839 /* Compare function to be passed to qsort to order the backarcs in descending
840    recMII order.  */
841 static int
842 compare_sccs (const void *s1, const void *s2)
843 {
844   const int rec_l1 = (*(const ddg_scc_ptr *)s1)->recurrence_length;
845   const int rec_l2 = (*(const ddg_scc_ptr *)s2)->recurrence_length; 
846   return ((rec_l2 > rec_l1) - (rec_l2 < rec_l1));
847           
848 }
849
850 /* Order the backarcs in descending recMII order using compare_sccs.  */
851 static void
852 order_sccs (ddg_all_sccs_ptr g)
853 {
854   qsort (g->sccs, g->num_sccs, sizeof (ddg_scc_ptr),
855          (int (*) (const void *, const void *)) compare_sccs);
856 }
857
858 #ifdef ENABLE_CHECKING
859 /* Check that every node in SCCS belongs to exactly one strongly connected
860    component and that no element of SCCS is empty.  */
861 static void
862 check_sccs (ddg_all_sccs_ptr sccs, int num_nodes)
863 {
864   int i = 0;
865   sbitmap tmp = sbitmap_alloc (num_nodes);
866
867   sbitmap_zero (tmp);
868   for (i = 0; i < sccs->num_sccs; i++)
869     {
870       gcc_assert (!sbitmap_empty_p (sccs->sccs[i]->nodes));
871       /* Verify that every node in sccs is in exactly one strongly
872          connected component.  */
873       gcc_assert (!sbitmap_any_common_bits (tmp, sccs->sccs[i]->nodes));
874       sbitmap_a_or_b (tmp, tmp, sccs->sccs[i]->nodes);
875     }
876   sbitmap_free (tmp);
877 }
878 #endif
879
880 /* Perform the Strongly Connected Components decomposing algorithm on the
881    DDG and return DDG_ALL_SCCS structure that contains them.  */
882 ddg_all_sccs_ptr
883 create_ddg_all_sccs (ddg_ptr g)
884 {
885   int i;
886   int num_nodes = g->num_nodes;
887   sbitmap from = sbitmap_alloc (num_nodes);
888   sbitmap to = sbitmap_alloc (num_nodes);
889   sbitmap scc_nodes = sbitmap_alloc (num_nodes);
890   ddg_all_sccs_ptr sccs = (ddg_all_sccs_ptr)
891                           xmalloc (sizeof (struct ddg_all_sccs));
892
893   sccs->ddg = g;
894   sccs->sccs = NULL;
895   sccs->num_sccs = 0;
896
897   for (i = 0; i < g->num_backarcs; i++)
898     {
899       ddg_scc_ptr  scc;
900       ddg_edge_ptr backarc = g->backarcs[i];
901       ddg_node_ptr src = backarc->src;
902       ddg_node_ptr dest = backarc->dest;
903
904       /* If the backarc already belongs to an SCC, continue.  */
905       if (backarc->aux.count == IN_SCC)
906         continue;
907
908       sbitmap_zero (scc_nodes);
909       sbitmap_zero (from);
910       sbitmap_zero (to);
911       SET_BIT (from, dest->cuid);
912       SET_BIT (to, src->cuid);
913
914       if (find_nodes_on_paths (scc_nodes, g, from, to))
915         {
916           scc = create_scc (g, scc_nodes);
917           add_scc_to_ddg (sccs, scc);
918         }
919     }
920   order_sccs (sccs);
921   sbitmap_free (from);
922   sbitmap_free (to);
923   sbitmap_free (scc_nodes);
924 #ifdef ENABLE_CHECKING
925   check_sccs (sccs, num_nodes);
926 #endif
927   return sccs;
928 }
929
930 /* Frees the memory allocated for all SCCs of the DDG, but keeps the DDG.  */
931 void
932 free_ddg_all_sccs (ddg_all_sccs_ptr all_sccs)
933 {
934   int i;
935
936   if (!all_sccs)
937     return;
938
939   for (i = 0; i < all_sccs->num_sccs; i++)
940     free_scc (all_sccs->sccs[i]);
941
942   free (all_sccs);
943 }
944
945 \f
946 /* Given FROM - a bitmap of source nodes - and TO - a bitmap of destination
947    nodes - find all nodes that lie on paths from FROM to TO (not excluding
948    nodes from FROM and TO).  Return nonzero if nodes exist.  */
949 int
950 find_nodes_on_paths (sbitmap result, ddg_ptr g, sbitmap from, sbitmap to)
951 {
952   int answer;
953   int change;
954   unsigned int u = 0;
955   int num_nodes = g->num_nodes;
956   sbitmap_iterator sbi;
957
958   sbitmap workset = sbitmap_alloc (num_nodes);
959   sbitmap reachable_from = sbitmap_alloc (num_nodes);
960   sbitmap reach_to = sbitmap_alloc (num_nodes);
961   sbitmap tmp = sbitmap_alloc (num_nodes);
962
963   sbitmap_copy (reachable_from, from);
964   sbitmap_copy (tmp, from);
965
966   change = 1;
967   while (change)
968     {
969       change = 0;
970       sbitmap_copy (workset, tmp);
971       sbitmap_zero (tmp);
972       EXECUTE_IF_SET_IN_SBITMAP (workset, 0, u, sbi)
973         {
974           ddg_edge_ptr e;
975           ddg_node_ptr u_node = &g->nodes[u];
976
977           for (e = u_node->out; e != (ddg_edge_ptr) 0; e = e->next_out)
978             {
979               ddg_node_ptr v_node = e->dest;
980               int v = v_node->cuid;
981
982               if (!TEST_BIT (reachable_from, v))
983                 {
984                   SET_BIT (reachable_from, v);
985                   SET_BIT (tmp, v);
986                   change = 1;
987                 }
988             }
989         }
990     }
991
992   sbitmap_copy (reach_to, to);
993   sbitmap_copy (tmp, to);
994
995   change = 1;
996   while (change)
997     {
998       change = 0;
999       sbitmap_copy (workset, tmp);
1000       sbitmap_zero (tmp);
1001       EXECUTE_IF_SET_IN_SBITMAP (workset, 0, u, sbi)
1002         {
1003           ddg_edge_ptr e;
1004           ddg_node_ptr u_node = &g->nodes[u];
1005
1006           for (e = u_node->in; e != (ddg_edge_ptr) 0; e = e->next_in)
1007             {
1008               ddg_node_ptr v_node = e->src;
1009               int v = v_node->cuid;
1010
1011               if (!TEST_BIT (reach_to, v))
1012                 {
1013                   SET_BIT (reach_to, v);
1014                   SET_BIT (tmp, v);
1015                   change = 1;
1016                 }
1017             }
1018         }
1019     }
1020
1021   answer = sbitmap_a_and_b_cg (result, reachable_from, reach_to);
1022   sbitmap_free (workset);
1023   sbitmap_free (reachable_from);
1024   sbitmap_free (reach_to);
1025   sbitmap_free (tmp);
1026   return answer;
1027 }
1028
1029
1030 /* Updates the counts of U_NODE's successors (that belong to NODES) to be
1031    at-least as large as the count of U_NODE plus the latency between them.
1032    Sets a bit in TMP for each successor whose count was changed (increased).
1033    Returns nonzero if any count was changed.  */
1034 static int
1035 update_dist_to_successors (ddg_node_ptr u_node, sbitmap nodes, sbitmap tmp)
1036 {
1037   ddg_edge_ptr e;
1038   int result = 0;
1039
1040   for (e = u_node->out; e; e = e->next_out)
1041     {
1042       ddg_node_ptr v_node = e->dest;
1043       int v = v_node->cuid;
1044
1045       if (TEST_BIT (nodes, v)
1046           && (e->distance == 0)
1047           && (v_node->aux.count < u_node->aux.count + e->latency))
1048         {
1049           v_node->aux.count = u_node->aux.count + e->latency;
1050           SET_BIT (tmp, v);
1051           result = 1;
1052         }
1053     }
1054   return result;
1055 }
1056
1057
1058 /* Find the length of a longest path from SRC to DEST in G,
1059    going only through NODES, and disregarding backarcs.  */
1060 int
1061 longest_simple_path (struct ddg * g, int src, int dest, sbitmap nodes)
1062 {
1063   int i;
1064   unsigned int u = 0;
1065   int change = 1;
1066   int result;
1067   int num_nodes = g->num_nodes;
1068   sbitmap workset = sbitmap_alloc (num_nodes);
1069   sbitmap tmp = sbitmap_alloc (num_nodes);
1070
1071
1072   /* Data will hold the distance of the longest path found so far from
1073      src to each node.  Initialize to -1 = less than minimum.  */
1074   for (i = 0; i < g->num_nodes; i++)
1075     g->nodes[i].aux.count = -1;
1076   g->nodes[src].aux.count = 0;
1077
1078   sbitmap_zero (tmp);
1079   SET_BIT (tmp, src);
1080
1081   while (change)
1082     {
1083       sbitmap_iterator sbi;
1084
1085       change = 0;
1086       sbitmap_copy (workset, tmp);
1087       sbitmap_zero (tmp);
1088       EXECUTE_IF_SET_IN_SBITMAP (workset, 0, u, sbi)
1089         {
1090           ddg_node_ptr u_node = &g->nodes[u];
1091
1092           change |= update_dist_to_successors (u_node, nodes, tmp);
1093         }
1094     }
1095   result = g->nodes[dest].aux.count;
1096   sbitmap_free (workset);
1097   sbitmap_free (tmp);
1098   return result;
1099 }