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