PIPS
scc.c File Reference
#include "local.h"
+ Include dependency graph for scc.c:

Go to the source code of this file.

Macros

#define NEW_MARK   1
 a set of macros to mark a vertex as 'not visited' or 'visited' and to check if a node has already been visited More...
 
#define OLD_MARK   2
 
#define MARK_OLD(v)
 
#define MARK_NEW(v)
 
#define MARKED_NEW_P(v)
 

Functions

void set_sccs_drivers (bool *ignore_this_vertex_fun, bool *ignore_this_successor_fun)
 
void reset_sccs_drivers ()
 
void LowlinkCompute (graph g, set region, vertex v, int level, sccs Components)
 
int IsInStack (vertex v)
 this function checks if vertex v is in the stack More...
 
sccs FindSccs (graph g, set region, int level)
 FindSccs is the interface function to compute the SCCs of a graph. More...
 
void ComputeInDegree (graph g, set region, int l)
 
list TopSortSccs (graph __attribute__((unused)) g, set region, int l, sccs Components)
 
list FindAndTopSortSccs (graph g, set region, int l)
 
void PrintScc (scc s)
 
void PrintSccs (sccs ss)
 

Variables

static int Count
 a set of variables shared by the functions of this package. More...
 
static int StackPointer
 
static vertexStack
 
static bool(* ignore_this_vertex_drv )(set, vertex)=0
 
static bool(* ignore_this_successor_drv )(vertex, set, successor, int)=0
 

Macro Definition Documentation

◆ MARK_NEW

#define MARK_NEW (   v)
Value:
#define sccflags_mark(x)
Definition: dg.h:275
#define dg_vertex_label_sccflags(x)
Definition: dg.h:237
#define vertex_vertex_label(x)
Definition: graph.h:152
#define NEW_MARK
a set of macros to mark a vertex as 'not visited' or 'visited' and to check if a node has already bee...
Definition: scc.c:57

Definition at line 62 of file scc.c.

◆ MARK_OLD

#define MARK_OLD (   v)
Value:

Definition at line 59 of file scc.c.

◆ MARKED_NEW_P

#define MARKED_NEW_P (   v)

◆ NEW_MARK

#define NEW_MARK   1

a set of macros to mark a vertex as 'not visited' or 'visited' and to check if a node has already been visited

#define MIN(a,b) ((a)>(b)?(b):(a))

Definition at line 57 of file scc.c.

◆ OLD_MARK

#define OLD_MARK   2

Definition at line 58 of file scc.c.

Function Documentation

◆ ComputeInDegree()

void ComputeInDegree ( graph  g,
set  region,
int  l 
)
Parameters
regionegion

Definition at line 244 of file scc.c.

244  {
246  {
247  if(!ignore_this_vertex_drv(region, v)) {
248  scc sv = VERTEX_ENCLOSING_SCC(v);
250  {
251  if(!ignore_this_successor_drv(v, region, su, l)) {
252  vertex s = successor_vertex(su);
253  scc ss = VERTEX_ENCLOSING_SCC(s);
254  if(sv != ss)
255  scc_indegree(ss) += 1;
256  }
257  }
258  }
259  }
260 }
#define scc_indegree(x)
Definition: dg.h:347
#define region
simulation of the type region
#define successor_vertex(x)
Definition: graph.h:118
#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 VERTEX(x)
VERTEX.
Definition: graph.h:122
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define VERTEX_ENCLOSING_SCC(v)
macros
Definition: rice-local.h:25
static bool(* ignore_this_successor_drv)(vertex, set, successor, int)=0
Definition: scc.c:82
static bool(* ignore_this_vertex_drv)(set, vertex)=0
Definition: scc.c:81

References FOREACH, graph_vertices, ignore_this_successor_drv, ignore_this_vertex_drv, region, scc_indegree, SUCCESSOR, successor_vertex, VERTEX, VERTEX_ENCLOSING_SCC, and vertex_successors.

Referenced by FindAndTopSortSccs().

+ Here is the caller graph for this function:

◆ FindAndTopSortSccs()

list FindAndTopSortSccs ( graph  g,
set  region,
int  l 
)
Parameters
regionegion

Definition at line 317 of file scc.c.

317  {
318  list lsccs;
320 
321  ifdebug(8) {
322  pips_debug(8, "Dependence graph:\n");
324  }
325 
326  pips_debug(3, "computing sccs ...\n");
327 
328  Components = FindSccs(g, region, l);
329 
330  pips_debug(3, "computing in degrees ...\n");
331 
332  ComputeInDegree(g, region, l);
333 
334  pips_debug(3, "topological sort ...\n");
335 
336  lsccs = TopSortSccs(g, region, l,Components);
337 
338 // free_sccs(Components);
340  free(Components);
341 
342 
343  return (lsccs);
344 }
#define sccs_sccs(x)
Definition: dg.h:311
void free(void *)
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define statement_undefined
Definition: ri.h:2419
void prettyprint_dependence_graph(FILE *, statement, graph)
Print all edges and arcs.
Definition: util.c:177
void ComputeInDegree(graph g, set region, int l)
Definition: scc.c:244
sccs FindSccs(graph g, set region, int level)
FindSccs is the interface function to compute the SCCs of a graph.
Definition: scc.c:206
list TopSortSccs(graph __attribute__((unused)) g, set region, int l, sccs Components)
Definition: scc.c:262
static sccs Components
Definition: sccdfg.c:126
#define ifdebug(n)
Definition: sg.c:47
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References Components, ComputeInDegree(), FindSccs(), free(), gen_free_list(), ifdebug, pips_debug, prettyprint_dependence_graph(), region, sccs_sccs, statement_undefined, and TopSortSccs().

Referenced by CodeGenerate(), SimplifyGraph(), and SupressDependances().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ FindSccs()

sccs FindSccs ( graph  g,
set  region,
int  level 
)

FindSccs is the interface function to compute the SCCs of a graph.

It marks all nodes as 'not visited' and then apply the main function LowlinkCompute on all vertices.

A vertex is processed only if it belongs to region. Later, successors will be processed if they can be reached through arcs whose level is greater or equal to level.

g is a graph

region and level define a sub-graph of g

Bug FOREACH

Parameters
regionegion
levelevel

Definition at line 206 of file scc.c.

206  {
207  list vertices = graph_vertices(g);
209 
210  Count = 1;
211  StackPointer = 0;
212  Stack = (vertex *)malloc(sizeof(vertex) * gen_length(vertices));
214  FOREACH(VERTEX, v, vertices) {
215  if(!ignore_this_vertex_drv(region, v)) {
218  if(fv == sccflags_undefined) {
219  pips_debug (7, "fv has not been set so far");
220  fv = make_sccflags(scc_undefined, 0, 0, 0);
221  dg_vertex_label_sccflags(lv) = fv;
222  }
223  sccflags_mark(fv) = NEW_MARK;
224  }
225  }
226  /* Bug FOREACH */FOREACH(VERTEX, v1, vertices) {
228  if(MARKED_NEW_P(v1)) {
230  }
231  }
232 
233  free(Stack);
234 
235  ifdebug(3) {
236  pips_debug(3, "Strongly connected components:\n");
238  pips_debug(3, "End\n");
239  }
240 
241  return (Components);
242 }
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
#define sccflags_undefined
Definition: dg.h:247
struct _newgen_struct_dg_vertex_label_ * dg_vertex_label
Definition: dg.h:68
#define scc_undefined
Definition: dg.h:321
void * malloc(YYSIZE_T)
#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 level
void PrintSccs(sccs ss)
Definition: scc.c:356
#define MARKED_NEW_P(v)
Definition: scc.c:65
void LowlinkCompute(graph g, set region, vertex v, int level, sccs Components)
Definition: scc.c:115
static vertex * Stack
Definition: scc.c:75
static int Count
a set of variables shared by the functions of this package.
Definition: scc.c:74
static int StackPointer
Definition: scc.c:74

References Components, Count, dg_vertex_label_sccflags, FOREACH, free(), gen_length(), graph_vertices, ifdebug, ignore_this_vertex_drv, level, LowlinkCompute(), make_sccflags(), make_sccs(), malloc(), MARKED_NEW_P, NEW_MARK, NIL, pips_debug, PrintSccs(), region, scc_undefined, sccflags_mark, sccflags_undefined, Stack, StackPointer, VERTEX, and vertex_vertex_label.

Referenced by FindAndTopSortSccs().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ IsInStack()

int IsInStack ( vertex  v)

this function checks if vertex v is in the stack

Definition at line 183 of file scc.c.

183  {
184  int i;
185 
186  for (i = 0; i < StackPointer; i++)
187  if(Stack[i] == v)
188  return (true);
189 
190  return (false);
191 }

References Stack, and StackPointer.

Referenced by LowlinkCompute().

+ Here is the caller graph for this function:

◆ LowlinkCompute()

void LowlinkCompute ( graph  g,
set  region,
vertex  v,
int  level,
sccs  Components 
)
Parameters
regionegion
levelevel
Componentsomponents

Definition at line 115 of file scc.c.

115  {
119 
120  pips_debug(7, "vertex is %zd (%zd %zd %zd)\n", statement_number(sv),
122 
123  MARK_OLD(v);
124 
125  sccflags_lowlink(fv) = Count;
126  sccflags_dfnumber(fv) = Count;
127 
128  Count++;
129 
130  Stack[StackPointer++] = v;
132 
133  if(!ignore_this_successor_drv(v, region, su, level)) {
134  vertex s = successor_vertex(su);
135 
136  if(!ignore_this_vertex_drv(region, s)) {
140 
141  pips_debug(7, "successor before is %zd (%zd %zd %zd)\n",
144 
145  if(MARKED_NEW_P(s)) {
147  pips_debug(7, "successor after is %zd (%zd %zd %zd)\n",
151  sccflags_lowlink(fs));
152  } else {
153  if((sccflags_dfnumber(fs) < sccflags_dfnumber(fv)) && IsInStack(s)) {
155  sccflags_lowlink(fv));
156  }
157  }
158  }
159  }
160  }
161 
162  if(sccflags_lowlink(fv) == sccflags_dfnumber(fv)) {
163  scc ns = make_scc(NIL, 0);
164  vertex p;
165  sccflags fp;
166  cons *pv = NIL;
167 
168  do {
169  p = Stack[--StackPointer];
172  sccflags_enclosing_scc(fp) = ns;
173  pv = gen_nconc(pv, CONS(VERTEX, p, NIL));
174  } while(v != p);
175 
176  scc_vertices(ns) = pv;
179  }
180 }
scc make_scc(list a1, intptr_t a2)
Definition: dg.c:306
#define MIN(x, y)
minimum and maximum if they are defined somewhere else, they are very likely to be defined the same w...
#define SCC(x)
SCC.
Definition: dg.h:315
#define dg_vertex_label_statement(x)
Definition: dg.h:235
#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 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
statement ordering_to_statement(int o)
Get the statement associated to a given ordering.
Definition: ordering.c:111
#define statement_number(x)
Definition: ri.h:2452
int IsInStack(vertex v)
this function checks if vertex v is in the stack
Definition: scc.c:183
#define MARK_OLD(v)
Definition: scc.c:59

References Components, CONS, Count, dg_vertex_label_sccflags, dg_vertex_label_statement, FOREACH, gen_nconc(), ignore_this_successor_drv, ignore_this_vertex_drv, IsInStack(), level, LowlinkCompute(), make_scc(), MARK_OLD, MARKED_NEW_P, MIN, NIL, ordering_to_statement(), pips_debug, region, SCC, scc_vertices, sccflags_dfnumber, sccflags_enclosing_scc, sccflags_lowlink, sccflags_mark, sccs_sccs, Stack, StackPointer, statement_number, SUCCESSOR, successor_vertex, VERTEX, vertex_successors, and vertex_vertex_label.

Referenced by FindSccs(), and LowlinkCompute().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ PrintScc()

void PrintScc ( scc  s)

Definition at line 346 of file scc.c.

346  {
347  fprintf(stderr, "Scc's statements : ");
348  FOREACH(VERTEX, v, scc_vertices(s)) {
350 
351  fprintf(stderr, "%02td ", statement_number(st));
352  }
353  fprintf(stderr, " - in degree : %td\n", scc_indegree(s));
354 }
statement vertex_to_statement(vertex v)
Vertex_to_statement looks for the statement that is pointed to by vertex v.
Definition: util.c:45
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...

References FOREACH, fprintf(), scc_indegree, scc_vertices, statement_number, VERTEX, and vertex_to_statement().

Referenced by ConnectedStatements(), and PrintSccs().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ PrintSccs()

void PrintSccs ( sccs  ss)
Parameters
sss

Definition at line 356 of file scc.c.

356  {
357  fprintf(stderr, "Strongly connected components:\n");
358  if(!ENDP(sccs_sccs(ss))) {
359  MAPL(ps, {PrintScc(SCC(CAR(ps)));}, sccs_sccs(ss));
360  } else {
361  fprintf(stderr, "Empty list of scc\n");
362  }
363 }
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#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
void PrintScc(scc s)
Definition: scc.c:346

References CAR, ENDP, fprintf(), MAPL, PrintScc(), SCC, and sccs_sccs.

Referenced by FindSccs().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reset_sccs_drivers()

void reset_sccs_drivers ( void  )

Definition at line 98 of file scc.c.

98  {
99  pips_assert( "ignore_this_vertex_drv is not set", ignore_this_vertex_drv != 0 );
100  pips_assert( "ignore_this_successor_drv is not set", ignore_this_successor_drv != 0 );
103 }
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172

References ignore_this_successor_drv, ignore_this_vertex_drv, and pips_assert.

Referenced by CodeGenerate(), SimplifyGraph(), and SupressDependances().

+ Here is the caller graph for this function:

◆ set_sccs_drivers()

void set_sccs_drivers ( bool ignore_this_vertex_fun,
bool ignore_this_successor_fun 
)

Definition at line 88 of file scc.c.

90 {
91  pips_assert( "ignore_this_vertex_drv is set", ignore_this_vertex_drv == 0 );
92  pips_assert( "ignore_this_successor_drv is set", ignore_this_successor_drv == 0 );
93 
94  ignore_this_vertex_drv = ignore_this_vertex_fun;
95  ignore_this_successor_drv = ignore_this_successor_fun;
96 }

References ignore_this_successor_drv, ignore_this_vertex_drv, and pips_assert.

◆ TopSortSccs()

list TopSortSccs ( graph __attribute__((unused))  g,
set  region,
int  l,
sccs  Components 
)

Definition at line 262 of file scc.c.

262  {
263  list lsccs = NIL, elsccs = NIL, no_ins = NIL;
265  if(scc_indegree(s) == 0)
266  no_ins = CONS(SCC, s, no_ins);
267  }
268 
269  while(no_ins != NIL) {
270  list pcs;
271  scc cs;
272 
273  pcs = no_ins;
274  no_ins = CDR(no_ins);
275  INSERT_AT_END(lsccs, elsccs, pcs);
276 
277  pips_debug(3, "updating in degrees ...\n");
278  cs = SCC(CAR(pcs));
279  FOREACH(VERTEX, v, scc_vertices(cs))
280  {
281  scc sv = VERTEX_ENCLOSING_SCC(v);
283  {
284  if(!ignore_this_successor_drv(v, region, su, l)) {
285  vertex s = successor_vertex(su);
286  scc ss = VERTEX_ENCLOSING_SCC(s);
287  if(sv != ss && (scc_indegree(ss) -= 1) == 0
288  && !ignore_this_vertex_drv(region, s)) {
289  no_ins = CONS(SCC, ss, no_ins);
290  }
291  }
292  }
293  }
294  }
295 
296  ifdebug(3) {
297  fprintf(stderr, "[TopSortSccs] topological order:\n");
298  FOREACH(SCC, s, lsccs) {
299  fprintf(stderr, "( ");
300  FOREACH(VERTEX, v, scc_vertices(s)) {
302 
303  fprintf(stderr, "%td ", statement_number(st));
304  }
305  fprintf(stderr, ") --> ");
306  }
307  fprintf(stderr, "\n");
308  }
309 
310  return (lsccs);
311 }
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define INSERT_AT_END(bl, el, c)
a macro to insert an element at the end of a list.
Definition: rice-local.h:34

References CAR, CDR, Components, CONS, FOREACH, fprintf(), ifdebug, ignore_this_successor_drv, ignore_this_vertex_drv, INSERT_AT_END, NIL, pips_debug, region, SCC, scc_indegree, scc_vertices, sccs_sccs, statement_number, SUCCESSOR, successor_vertex, VERTEX, VERTEX_ENCLOSING_SCC, vertex_successors, and vertex_to_statement().

Referenced by FindAndTopSortSccs().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ Count

int Count
static

a set of variables shared by the functions of this package.

the stack contains the current SCC, i.e. the SCC currently being built. Components is the result, i.e. a set of scc

Definition at line 74 of file scc.c.

Referenced by FindSccs(), and LowlinkCompute().

◆ ignore_this_successor_drv

bool(* ignore_this_successor_drv) (vertex, set, successor, int)=0 ( vertex  ,
set  ,
successor  ,
int   
)
static

◆ ignore_this_vertex_drv

bool(* ignore_this_vertex_drv) (set, vertex)=0 ( set  ,
vertex   
)
static

◆ Stack

vertex* Stack
static

Definition at line 75 of file scc.c.

Referenced by FindSccs(), IsInStack(), and LowlinkCompute().

◆ StackPointer

int StackPointer
static

Definition at line 74 of file scc.c.

Referenced by FindSccs(), IsInStack(), and LowlinkCompute().