PIPS
sccdfg.c
Go to the documentation of this file.
1 /*
2 
3  $Id: sccdfg.c 23065 2016-03-02 09:05:50Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 
28 #ifndef lint
29 char vcid_scheduling_sccdfg[] = "$Id: sccdfg.c 23065 2016-03-02 09:05:50Z coelho $";
30 #endif /* lint */
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <limits.h>
36 
37 #include "genC.h"
38 
39 #include "boolean.h"
40 #include "vecteur.h"
41 #include "contrainte.h"
42 #include "sc.h"
43 #include "ray_dte.h"
44 #include "sommet.h"
45 #include "sg.h"
46 #include "polyedre.h"
47 #include "union.h"
48 #include "matrix.h"
49 
50 #include "ri.h"
51 #include "graph.h"
52 #include "dg.h"
53 
54 #include "misc.h"
55 #include "ri-util.h"
56 #include "properties.h"
57 
58 
59 #include "constants.h"
60 #include "rice.h"
61 #include "ricedg.h"
62 
63 #include "complexity_ri.h"
64 #include "database.h"
65 #include "parser_private.h"
66 #include "property.h"
67 #include "reduction.h"
68 #include "tiling.h"
69 
70 #include "text.h"
71 #include "text-util.h"
72 #include "graph.h"
73 #include "pipsdbm.h"
74 #include "paf_ri.h"
75 #include "paf-util.h"
76 #include "resources.h"
77 #include "scheduling.h"
78 
79 
80 /* instantiation of the dependence graph */
81 
84 
85 /*====================================================================*/
86 /* This collection of functions implements Tarjan's algorithm to find
87  * the strongly connected components of a directed graph.
88  *
89  * this algorithm is presented in:
90  * Types de Donnees et Algorithmes
91  * Recherche, Tri, Algorithmes sur les Graphes
92  * Marie-Claude Gaudel, Michele Soria, Christine Froidevaux
93  * Collection Didactique
94  * INRIA
95  *====================================================================*/
96 
97 
98 /* A set of macros to mark a vertex as 'not visited' or 'visited' and */
99 /* to check if a node has already been visited. */
100 
101 #define MY_MIN(a,b) ((a)>(b)?(b):(a))
102 
103 #define NEW_MARK 1
104 #define OLD_MARK 2
105 #define DFG_MARK_OLD(v) \
106  (sccflags_mark(dfg_vertex_label_sccflags((dfg_vertex_label) \
107  vertex_vertex_label(v))) = OLD_MARK)
108 #define DFG_MARK_NEW(v) \
109  (sccflags_mark(dfg_vertex_label_sccflags((dfg_vertex_label) \
110  vertex_vertex_label(v))) = NEW_MARK)
111 #define DFG_MARKED_NEW_P(v) \
112  (sccflags_mark(dfg_vertex_label_sccflags((dfg_vertex_label) \
113  vertex_vertex_label(v))) == NEW_MARK)
114 
115 #define DFG_VERTEX_ENCLOSING_SCC(v) \
116  (sccflags_enclosing_scc(dfg_vertex_label_sccflags((dfg_vertex_label)\
117  vertex_vertex_label(v))))
118 
119 
120 /* A set of variables shared by the functions of this package. The */
121 /* stack contains the current SCC, i.e. the SCC currently being */
122 /* built. Components is the result, i.e. a set of scc. */
123 
124 static int Count, StackPointer;
125 static vertex *Stack;
127 
128 /*==================================================================*/
129 /* int dfg_is_in_stack(v) : this function checks if vertex v is in the
130  * stack.
131  *
132  * AC 93/10/18
133  */
134 
136 
137  vertex v;
138 {
139  int i;
140 
141  for (i = 0; i < StackPointer; i++)
142  if (Stack[i] == v) return(true);
143 
144  return(false);
145 }
146 
147 /*==================================================================*/
148 /* dfg_low_link_compute() is the main function. Its behavior is
149  * explained in the book mentionned ealier.
150  *
151  * AC 93/10/18
152  */
153 
155 
156  graph g;
157  vertex v;
158 {
161 
162  DFG_MARK_OLD(v);
163 
164  sccflags_lowlink(fv) = Count;
165  sccflags_dfnumber(fv) = Count;
166 
167  Count ++;
168 
169  Stack[StackPointer++] = v;
170 
171  MAPL(ps, {
173  if (s != (vertex)NIL)
174  {
177  if (DFG_MARKED_NEW_P(s))
178  {
179  dfg_low_link_compute(g, s);
181  sccflags_lowlink(fs));
182  }
183  else
184  {
185  if ((sccflags_dfnumber(fs) < sccflags_dfnumber(fv)) &&\
186  dfg_is_in_stack(s))
188  sccflags_lowlink(fv));
189  }
190  }
191  }, vertex_successors(v));
192 
193  if (sccflags_lowlink(fv) == sccflags_dfnumber(fv))
194  {
195  scc ns = make_scc(NIL, 0);
196  vertex p;
197  sccflags fp;
198  cons *pv = NIL;
199 
200  do
201  {
202  p = Stack[--StackPointer];
205  sccflags_enclosing_scc(fp) = ns;
206  pv = gen_nconc(pv, CONS(VERTEX, p, NIL));
207  } while (v != p);
208 
209  scc_vertices(ns) = pv;
211  CONS(SCC, ns, NIL));
212  }
213 }
214 
215 /*==================================================================*/
216 /* dfg_find_sccs is the interface function to compute the SCCs of a
217  * graph. It marks all nodes as 'not visited' and then apply the
218  * main function dfg_low_link_compute() on all vertices.
219  *
220  * AC 93/10/19
221  */
222 
224 
225  graph g;
226 {
227  cons *vertices = graph_vertices(g), *pv;
228 
229  Count = 1;
230  StackPointer = 0;
231  Stack = (vertex *)malloc(sizeof(vertex) * gen_length(vertices));
233 
234  for (pv = vertices; pv != NIL; pv = CDR(pv))
235  {
236  vertex v = VERTEX(CAR(pv));
239  }
240 
241  MAPL(pv, {
242  vertex v = VERTEX(CAR(pv));
244  }, vertices);
245 
246  free(Stack);
247 
248  return(Components);
249 }
250 
251 /*============================================================================*/
252 /* void fprint_sccs(FILE *fp, sccs obj): prints in the file "fp" the
253  * list of strongly connected components "obj".
254  *
255  * AC 93/10/20
256  */
257 
258 void fprint_sccs(fp, obj)
259 
260  FILE *fp;
261  sccs obj;
262 {
263  list nodes_l, su_l, df_l, scc_l;
264  int source_stmt, sink_stmt;
265  int iter = 0;
266 
267  fprintf(fp,"\n Graphe des Composantes Connexes :\n");
268  fprintf(fp,"==================================\n");
269 
270  for(scc_l = sccs_sccs(obj); scc_l != NIL; scc_l = CDR(scc_l))
271  {
272  scc scc_an = SCC(CAR(scc_l));
273  iter++;
274  fprintf(fp,"\ncomposante %d :\n",iter);
275  for(nodes_l=scc_vertices(scc_an);nodes_l !=NIL;nodes_l=CDR(nodes_l))
276  {
277  vertex crt_v = VERTEX(CAR(nodes_l));
278  source_stmt = vertex_int_stmt(crt_v);
279  fprintf(fp,"\tins_%d:\n", source_stmt);
280  su_l = vertex_successors(crt_v);
281  for( ; su_l != NIL; su_l = CDR(su_l))
282  {
283  successor su = SUCCESSOR(CAR(su_l));
286  for ( ; df_l != NIL; df_l = CDR(df_l))
287  fprint_dataflow(fp, sink_stmt, DATAFLOW(CAR(df_l)));
288  }
289  }
290  }
291 }
292 
293 /*==================================================================*/
294 /* The following functions are used to build the reverse graph of a
295  * dataflow graph
296  *==================================================================*/
297 
298 /*==================================================================*/
299 /* vertex dfg_in_vertex_list((list) l, (vertex) v):
300  * Input : A list l of vertices.
301  * A vertex v of a dataflow graph.
302  * Returns vertex_undefined if v is not in list l.
303  * Returns v' that has the same statement_ordering than v.
304  *
305  * AC 93/10/19
306  */
307 
309 
310  list l;
311  vertex v;
312 {
313  vertex ver;
314  int p, i;
315 
318  for ( ; !ENDP(l); POP(l))
319  {
320  ver = VERTEX(CAR(l));
322  vertex_vertex_label(ver));
323  if (p == i) return(ver);
324  }
325 
326  return (vertex_undefined);
327 }
328 
329 
330 /*=======================================================================*/
331 /* graph dfg_reverse_graph((graph) g):
332  * This function is used to reverse Pips's graph in order to have
333  * all possible sources directly (Feautrier's dependance graph).
334  *
335  * AC 93/10/19
336  */
337 
338 
340 
341  graph g;
342 {
343  graph rev_graph = graph_undefined;
344  list vlist = NIL, li = NIL;
345  successor succ, succ2;
346  vertex v1, v2, v3, v4, v5;
347 
348  MAPL(ver_ptr,{
349  v1 = VERTEX(CAR(ver_ptr));
350  v5 = dfg_in_vertex_list(vlist, v1);
351  if (v5 == vertex_undefined)
352  {
354  vertex_vertex_label(v1)), NIL);
355  ADD_ELEMENT_TO_LIST(vlist, VERTEX, v2);
356  }
357  else v2 = v5;
358 
359  MAPL(succ_ptr, {
360  li = NIL;
361  succ = SUCCESSOR(CAR(succ_ptr));
362  v3 = successor_vertex(succ);
363  v5 = dfg_in_vertex_list(vlist, v3);
364  succ2 = make_successor((dfg_arc_label)\
365  successor_arc_label(succ), v2);
366  if (v5 == vertex_undefined)
367  {
368  ADD_ELEMENT_TO_LIST(li, SUCCESSOR, succ2);
370  vertex_vertex_label(v3)), li);
371  ADD_ELEMENT_TO_LIST(vlist, VERTEX, v4);
372  }
373  else
375  SUCCESSOR, succ2);
376  }, vertex_successors(v1));
377  }, graph_vertices(g));
378  rev_graph = make_graph(vlist);
379 
380  return(rev_graph);
381 }
382 
383 /***********************************************************************/
sccs make_sccs(list a)
Definition: dg.c:264
sccflags make_sccflags(scc a1, intptr_t a2, intptr_t a3, intptr_t a4)
Definition: dg.c:222
scc make_scc(list a1, intptr_t a2)
Definition: dg.c:306
graph make_graph(list a)
Definition: graph.c:56
successor make_successor(arc_label a1, vertex a2)
Definition: graph.c:98
vertex make_vertex(vertex_label a1, list a2)
Definition: graph.c:140
dfg_vertex_label copy_dfg_vertex_label(dfg_vertex_label p)
DFG_VERTEX_LABEL.
Definition: paf_ri.c:228
static int sink_stmt
Current source node.
Definition: adg_read_paf.c:160
static int source_stmt
Current sink statement.
Definition: adg_read_paf.c:161
#define SCC(x)
SCC.
Definition: dg.h:315
#define sccflags_lowlink(x)
Definition: dg.h:279
#define sccflags_enclosing_scc(x)
Definition: dg.h:273
#define scc_vertices(x)
Definition: dg.h:345
#define sccflags_dfnumber(x)
Definition: dg.h:277
#define scc_undefined
Definition: dg.h:321
#define sccs_sccs(x)
Definition: dg.h:311
void * malloc(YYSIZE_T)
void free(void *)
#define successor_vertex(x)
Definition: graph.h:118
#define vertex_undefined
Definition: graph.h:128
#define successor_arc_label(x)
Definition: graph.h:116
#define vertex_vertex_label(x)
Definition: graph.h:152
#define vertex_successors(x)
Definition: graph.h:154
#define SUCCESSOR(x)
SUCCESSOR.
Definition: graph.h:86
#define graph_vertices(x)
Definition: graph.h:82
#define graph_undefined
Definition: graph.h:60
#define VERTEX(x)
VERTEX.
Definition: graph.h:122
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
size_t gen_length(const list l)
Definition: list.c:150
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define MAPL(_map_list_cp, _code, _l)
Apply some code on the addresses of all the elements of a list.
Definition: newgen_list.h:203
#define ADD_ELEMENT_TO_LIST(_list, _type, _element)
Definition: icfg-local.h:50
int vertex_int_stmt(vertex)
===========================================================================
Definition: utils.c:866
void fprint_dataflow(FILE *, int, dataflow)
===========================================================================
Definition: print.c:229
#define DATAFLOW(x)
DATAFLOW.
Definition: paf_ri.h:308
#define dfg_vertex_label_sccflags(x)
Definition: paf_ri.h:417
#define dfg_arc_label_dataflows(x)
Definition: paf_ri.h:378
struct _newgen_struct_dfg_vertex_label_ * dfg_vertex_label
Definition: paf_ri.h:112
#define dfg_vertex_label_statement(x)
Definition: paf_ri.h:413
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
#define DFG_MARK_OLD(v)
Definition: sccdfg.c:105
static sccs Components
Definition: sccdfg.c:126
graph dfg_reverse_graph(graph g)
======================================================================
Definition: sccdfg.c:339
dfg_arc_label arc_label
lint
Definition: sccdfg.c:82
vertex dfg_in_vertex_list(list l, vertex v)
=================================================================
Definition: sccdfg.c:308
#define MY_MIN(a, b)
===================================================================
Definition: sccdfg.c:101
void dfg_low_link_compute(graph g, vertex v)
=================================================================
Definition: sccdfg.c:154
int dfg_is_in_stack(vertex v)
=================================================================
Definition: sccdfg.c:135
static vertex * Stack
Definition: sccdfg.c:125
dfg_vertex_label vertex_label
Definition: sccdfg.c:83
sccs dfg_find_sccs(graph g)
=================================================================
Definition: sccdfg.c:223
#define DFG_MARKED_NEW_P(v)
Definition: sccdfg.c:111
char vcid_scheduling_sccdfg[]
Definition: sccdfg.c:29
static int Count
A set of variables shared by the functions of this package.
Definition: sccdfg.c:124
static int StackPointer
Definition: sccdfg.c:124
void fprint_sccs(FILE *fp, sccs obj)
===========================================================================
Definition: sccdfg.c:258
The structure used to build lists in NewGen.
Definition: newgen_list.h:41