PIPS
rice.h File Reference
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define VERTEX_ENCLOSING_SCC(v)
 Warning! Do not modify this file that is automatically generated! More...
 
#define INSERT_AT_END(bl, el, c)    { cons *_insert_ = c; if (bl == NIL) bl = _insert_; else CDR(el) = _insert_; el = _insert_; CDR(el) = NIL; }
 a macro to insert an element at the end of a list. More...
 

Functions

void rice_unstructured (unstructured, int, statement(*)(statement, graph, set, int, bool))
 
statement rice_statement (statement, int, statement(*)(statement, graph, set, int, bool))
 
statement rice_loop (statement, int, statement(*)(statement, graph, set, int, bool))
 Eventually parallelize a do-loop with à la Rice algorithm. More...
 
bool do_it (string, bool, string, statement(*)(statement, graph, set, int, bool))
 
bool distributer (string)
 
bool rice_all_dependence (string)
 
bool rice_data_dependence (string)
 
bool rice_cray (string)
 
bool ignore_this_conflict (vertex, vertex, conflict, int)
 codegen.c More...
 
statement find_level_l_loop_statement (scc, int)
 s is a strongly connected component which is analyzed at level l. More...
 
set scc_region (scc)
 
bool contains_level_l_dependence (scc, set, int)
 s is a strongly connected component for which a DO loop is being produced. More...
 
bool strongly_connected_p (scc, int)
 this function returns true if scc s is stronly connected at level l, i.e. More...
 
statement MakeNestOfParallelLoops (int, cons *, statement, bool)
 this function creates a nest of parallel loops around an isolated statement whose iterations may execute in parallel. More...
 
int statement_imbrication_level (statement)
 
statement MakeNestOfStatementList (int, int, list *, list, list *, list *, bool)
 
statement CodeGenerate (statement, graph, set, int, bool)
 
statement MakeLoopAs (statement, tag, statement)
 This function creates a new loop whose characteristics (index, bounds, ...) are similar to those of old_loop. More...
 
statement IsolatedStatement (scc, int, bool)
 If the isolated statement is a CALL and is not a CONTINUE, regenerate the nested loops around it. More...
 
statement ConnectedStatements (graph, scc, int, bool)
 BB: ConnectedStatements() is called when s contains more than one vertex or one vertex dependent upon itself. More...
 
void set_sccs_drivers (bool(*)(set, vertex), bool(*)(vertex, set, successor, int))
 scc.c More...
 
void reset_sccs_drivers (void)
 
void LowlinkCompute (graph, set, vertex, int, sccs)
 
int IsInStack (vertex)
 this function checks if vertex v is in the stack More...
 
sccs FindSccs (graph, set, int)
 FindSccs is the interface function to compute the SCCs of a graph. More...
 
void ComputeInDegree (graph, set, int)
 
list TopSortSccs (graph, set, int, sccs)
 
list FindAndTopSortSccs (graph, set, int)
 
void PrintScc (scc)
 
void PrintSccs (sccs)
 
void dump_sef (statement_effects)
 icm.c More...
 
void print_list_entities (list)
 
bool invariant_code_motion (const char *)
 Phase that hoists loop invariant code out of loops. More...
 

Variables

graph dg
 external variables. More...
 
bool rice_distribute_only
 to know if do loop parallelization must be done More...
 
int Nbrdoall
 
int enclosing
 This is an horrendous hack. More...
 

Macro Definition Documentation

◆ INSERT_AT_END

#define INSERT_AT_END (   bl,
  el,
 
)     { cons *_insert_ = c; if (bl == NIL) bl = _insert_; else CDR(el) = _insert_; el = _insert_; CDR(el) = NIL; }

a macro to insert an element at the end of a list.

c is the element to insert. bl and el are pointers to the begining and the end of the list.

Definition at line 42 of file rice.h.

◆ VERTEX_ENCLOSING_SCC

#define VERTEX_ENCLOSING_SCC (   v)
Value:
#define sccflags_enclosing_scc(x)
Definition: dg.h:273
#define dg_vertex_label_sccflags(x)
Definition: dg.h:237
#define vertex_vertex_label(x)
Definition: graph.h:152

Warning! Do not modify this file that is automatically generated!

Modify src/Libs/rice/rice-local.h instead, to add your own modifications. header file built by cproto rice-local.h macros

Definition at line 33 of file rice.h.

Function Documentation

◆ CodeGenerate()

statement CodeGenerate ( statement  ,
graph  ,
set  ,
int  ,
bool   
)

◆ 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:

◆ ConnectedStatements()

statement ConnectedStatements ( graph  g,
scc  s,
int  l,
bool  task_parallelize_p 
)

BB: ConnectedStatements() is called when s contains more than one vertex or one vertex dependent upon itself.

Thus, vectorization can't occur.

FI: it may not be true if one of the statements is a C declaration.

At most one outer loop parallel

CodeGenerate does not use the first parameter...

big hack

Parameters
task_parallelize_pask_parallelize_p

Definition at line 614 of file codegen.c.

614  {
615  extern int enclosing;
617  loop lo = statement_loop(slo);
618  statement inner_stat;
619  set inner_region;
620  tag seq_or_par;
621  bool task_parallelize_inner;
622 
623  pips_debug(8, "at level %d:\n",l);
624  ifdebug(8)
625  PrintScc(s);
626 
627  inner_region = scc_region(s);
628  seq_or_par = (!task_parallelize_p
629  || contains_level_l_dependence(s, inner_region, l)
632 
633  /* At most one outer loop parallel */
634  task_parallelize_inner
635  = (seq_or_par == is_execution_parallel
636  && !get_bool_property("GENERATE_NESTED_PARALLEL_LOOPS")) ? false
637  : task_parallelize_p;
638 
639  /* CodeGenerate does not use the first parameter... */
640  inner_stat = CodeGenerate(/* big hack */statement_undefined,
641  g,
642  inner_region,
643  l + 1,
644  task_parallelize_inner);
645 
646  set_free(inner_region);
647 
648  if(statement_undefined_p(inner_stat))
649  return inner_stat;
650  else
651  return MakeLoopAs(slo, seq_or_par, inner_stat);
652 }
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
if(!(yy_init))
Definition: genread_lex.c:1029
bool index_private_p(loop lo)
returns true if loop lo's index is private for this loop
Definition: loop.c:240
loop statement_loop(statement)
Get the loop of a statement.
Definition: statement.c:1374
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
void set_free(set)
Definition: set.c:332
int tag
TAG.
Definition: newgen_types.h:92
#define false
Definition: newgen_types.h:80
@ is_execution_parallel
Definition: ri.h:1190
@ is_execution_sequential
Definition: ri.h:1189
#define statement_undefined_p(x)
Definition: ri.h:2420
#define statement_undefined
Definition: ri.h:2419
statement MakeLoopAs(statement old_loop_statement, tag seq_or_par, statement body)
This function creates a new loop whose characteristics (index, bounds, ...) are similar to those of o...
Definition: codegen.c:517
bool contains_level_l_dependence(scc s, set region, int level)
s is a strongly connected component for which a DO loop is being produced.
Definition: codegen.c:239
set scc_region(scc s)
Definition: codegen.c:226
statement find_level_l_loop_statement(scc s, int l)
s is a strongly connected component which is analyzed at level l.
Definition: codegen.c:213
statement CodeGenerate(statement __attribute__((unused)) stat, graph g, set region, int l, bool task_parallelize_p)
This function implements Allen & Kennedy's algorithm.
Definition: codegen.c:393
int enclosing
This is an horrendous hack.
Definition: rice.c:67
void PrintScc(scc)
Definition: scc.c:346
else
Definition: set.c:239
return(s1)
#define ifdebug(n)
Definition: sg.c:47
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59

References CodeGenerate(), contains_level_l_dependence(), enclosing, find_level_l_loop_statement(), get_bool_property(), ifdebug, index_private_p(), is_execution_parallel, is_execution_sequential, MakeLoopAs(), pips_debug, PrintScc(), scc_region(), set_free(), statement_loop(), statement_undefined, and statement_undefined_p.

Referenced by CodeGenerate().

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

◆ contains_level_l_dependence()

bool contains_level_l_dependence ( scc  s,
set  region,
int  level 
)

s is a strongly connected component for which a DO loop is being produced.

this function returns false if s contains no dependences at level l. in this case, the loop will be a DOALL loop.

Parameters
regionegion
levelevel

Definition at line 239 of file codegen.c.

239  {
240  FOREACH(VERTEX, v, scc_vertices(s)) {
243  {
244  vertex vs = successor_vertex(su);
246 
247  if(!AK_ignore_this_vertex(region, vs)) {
250  {
251  if(!ignore_this_conflict(v, vs, c, level)) {
252  if(conflict_cone(c) != cone_undefined) {
253  FOREACH(int, l, cone_levels(conflict_cone(c)))
254  {
255  if(l == level) {
256  ifdebug(7) {
257  pips_debug(7, "containing conflit at level %d: ",level);
258  fprintf(stderr,
259  "\t%02td --> %02td ",
261  statement_number(s2));
262  fprintf(stderr, "\t\tfrom ");
264  fprintf(stderr, " to ");
266  fprintf(stderr, "\n");
267  }
268  return (true);
269  }
270  }
271  }
272  }
273  }
274  }
275  }
276  }
277 
278  return (false);
279 }
struct _newgen_struct_dg_arc_label_ * dg_arc_label
Definition: dg.h:60
#define conflict_sink(x)
Definition: dg.h:167
#define cone_levels(x)
Definition: dg.h:128
#define CONFLICT(x)
CONFLICT.
Definition: dg.h:134
#define dg_arc_label_conflicts(x)
Definition: dg.h:201
#define scc_vertices(x)
Definition: dg.h:345
#define conflict_source(x)
Definition: dg.h:165
#define cone_undefined
Definition: dg.h:104
#define conflict_cone(x)
Definition: dg.h:169
#define successor_arc_label(x)
Definition: graph.h:116
statement vertex_to_statement(vertex v)
Vertex_to_statement looks for the statement that is pointed to by vertex v.
Definition: util.c:45
#define print_effect(e)
Definition: print.c:336
#define statement_number(x)
Definition: ri.h:2452
static bool AK_ignore_this_vertex(set region, vertex v)
Definition: codegen.c:70
bool ignore_this_conflict(vertex v1, vertex v2, conflict c, int l)
This function checks if conflict c between vertices v1 and v2 should be ignored at level l.
Definition: codegen.c:163
#define level
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
s1
Definition: set.c:247

References AK_ignore_this_vertex(), cone_levels, cone_undefined, CONFLICT, conflict_cone, conflict_sink, conflict_source, dg_arc_label_conflicts, FOREACH, fprintf(), ifdebug, ignore_this_conflict(), level, pips_debug, print_effect, region, s1, scc_vertices, statement_number, SUCCESSOR, successor_arc_label, successor_vertex, VERTEX, vertex_successors, and vertex_to_statement().

Referenced by ConnectedStatements().

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

◆ distributer()

bool distributer ( string  mod_name)
Parameters
mod_nameod_name

Definition at line 354 of file rice.c.

354  {
355  bool success;
356 
357  debug_on("RICE_DEBUG_LEVEL");
358 
360  /*
361  * For C code, this pass requires that effects are calculated with property
362  * MEMORY_EFFECTS_ONLY set to false because we need that the Chains includes
363  * arcs for declarations as these latter are separate statements now.
364  */
365  bool memory_effects_only_p = get_bool_property("MEMORY_EFFECTS_ONLY");
366  if(c_module_p(module) && memory_effects_only_p) {
367  // user error? internal error?
368  pips_user_warning("Distributer should be run with property "
369  "MEMORY_EFFECTS_ONLY set to FALSE.");
370  return false; // return to pass manager with a failure code
371  }
372 
373  success = do_it(mod_name, true, DBR_CODE, &CodeGenerate);
374 
375  debug_off();
376 
377  return success;
378 }
bool success
Definition: gpips-local.h:59
#define debug_on(env)
Definition: misc-local.h:157
#define pips_user_warning
Definition: misc-local.h:146
#define debug_off()
Definition: misc-local.h:160
static char * module
Definition: pips.c:74
entity local_name_to_top_level_entity(const char *n)
This function try to find a top-level entity from a local name.
Definition: entity.c:1450
bool c_module_p(entity m)
Test if a module "m" is written in C.
Definition: entity.c:2777
bool do_it(string mod_name, bool distribute_p, string what, statement(*codegen_fun)(statement, graph, set, int, bool))
Definition: rice.c:261

References c_module_p(), CodeGenerate(), debug_off, debug_on, do_it(), get_bool_property(), local_name_to_top_level_entity(), module, and pips_user_warning.

+ Here is the call graph for this function:

◆ do_it()

bool do_it ( string  mod_name,
bool  distribute_p,
string  what,
statement(*)(statement, graph, set, int, bool codegen_fun 
)

In spite of its name, the new statement "mod_parallel_stat" may be sequential if distribute_p is true

Make sure the dependence graph points towards the code copy

Regenerate statement_ordering for the parallel code

FI: This may be parallel or sequential code

Parameters
mod_nameod_name
distribute_pistribute_p
whathat

Definition at line 261 of file rice.c.

264  {
267 
269  /* In spite of its name, the new statement "mod_parallel_stat"
270  * may be sequential if distribute_p is true
271  */
272  statement mod_parallel_stat = statement_undefined;
273 
275  mod_name,
276  true));
278 
279  debug_on("RICE_DEBUG_LEVEL");
280 
281  print_parallelization_statistics(mod_name, "ante", mod_stat);
282 
283  ifdebug(7) {
284  pips_debug(7, "\nTesting NewGen consistency for initial code %s:\n",
285  mod_name);
287  fprintf(stderr, " NewGen consistent statement\n");
288  }
289 
290  ifdebug(1) {
291  debug(1, "do_it", "original sequential code:\n\n");
293  }
294 
295  mod_parallel_stat = copy_statement(mod_stat);
296 
297  ifdebug(7) {
298  debug(7,
299  "do_it",
300  "\nTesting NewGen consistency for copy code %s:",
301  mod_name);
302  if(statement_consistent_p((statement)mod_parallel_stat))
303  fprintf(stderr, " NewGen consistent statement copy\n");
304  }
305 
306  ifdebug(1) {
307  debug(1, "do_it", "copy of sequential code:\n\n");
309  }
310 
311  if(graph_undefined_p(dg)) {
312  dg = (graph)db_get_memory_resource(DBR_DG, mod_name, true);
313  } else {
314  pips_internal_error("dg should be undefined");
315  }
316 
317  /* Make sure the dependence graph points towards the code copy */
318  set_ordering_to_statement(mod_parallel_stat);
319 
320  rice_distribute_only = distribute_p;
321  enclosing = 0;
322  // rice_statement works by side effects, most of the times, but
323  // not for loops
324  mod_parallel_stat = rice_statement(mod_parallel_stat, 1, codegen_fun);
325 
326  /* Regenerate statement_ordering for the parallel code */
328  module_body_reorder(mod_parallel_stat);
330 
331  (void)update_loops_locals(mod_name, mod_parallel_stat);
332 
333  ifdebug(7) {
334  pips_debug(7, "\nparallelized code for module %s:", mod_name);
335  if(statement_consistent_p(mod_parallel_stat))
336  fprintf(stderr, " gen consistent\n");
337  print_parallel_statement(mod_parallel_stat);
338  }
339 
340  debug_off();
341  clean_up_sequences(mod_parallel_stat);
342 
343  /* FI: This may be parallel or sequential code */DB_PUT_MEMORY_RESOURCE(what, mod_name, mod_parallel_stat);
344 
345  print_parallelization_statistics(mod_name, "post", mod_parallel_stat);
346 
349  return true;
350 }
statement copy_statement(statement p)
STATEMENT.
Definition: ri.c:2186
bool statement_consistent_p(statement p)
Definition: ri.c:2195
bool clean_up_sequences(statement s)
Recursively clean up the statement sequences by fusing them if possible and by removing useless one.
bool update_loops_locals(const char *, statement)
struct _newgen_struct_graph_ * graph
Definition: graph.h:31
#define graph_undefined_p(x)
Definition: graph.h:61
#define graph_undefined
Definition: graph.h:60
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
void print_parallelization_statistics(const char *module, const char *msg, statement s)
Print out the number of sequential versus parallel loops.
Definition: loop.c:814
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
Definition: database.c:755
#define DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
Definition: pipsdbm-local.h:66
static statement mod_stat
We want to keep track of the current statement inside the recurse.
Definition: impact_check.c:41
#define pips_internal_error
Definition: misc-local.h:149
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
hash_table set_ordering_to_statement(statement s)
To be used instead of initialize_ordering_to_statement() to make sure that the hash table ots is in s...
Definition: ordering.c:172
void reset_ordering_to_statement(void)
Reset the mapping from ordering to statement.
Definition: ordering.c:185
void print_parallel_statement(statement)
Definition: statement.c:156
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
bool module_body_reorder(statement body)
Reorder a module.
Definition: reorder.c:211
bool rice_distribute_only
to know if do loop parallelization must be done
Definition: rice.c:62
statement rice_statement(statement stat, int l, statement(*codegen_fun)(statement, graph, set, int, bool))
Definition: rice.c:82
graph dg
Remi Triolet.
Definition: rice.c:59

References clean_up_sequences(), copy_statement(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug(), debug_off, debug_on, dg, enclosing, fprintf(), get_current_module_statement(), graph_undefined, graph_undefined_p, ifdebug, local_name_to_top_level_entity(), mod_stat, module, module_body_reorder(), pips_debug, pips_internal_error, print_parallel_statement(), print_parallelization_statistics(), print_statement(), reset_current_module_entity(), reset_current_module_statement(), reset_ordering_to_statement(), rice_distribute_only, rice_statement(), set_current_module_entity(), set_current_module_statement(), set_ordering_to_statement(), statement_consistent_p(), statement_undefined, and update_loops_locals().

Referenced by distributer(), and rice().

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

◆ dump_sef()

void dump_sef ( statement_effects  se)

icm.c

Parameters
see

Definition at line 75 of file icm.c.

76 {
77  fprintf(stderr, "\n");
78  STATEMENT_EFFECTS_MAP(s, e, {
79  fprintf(stderr,
80  "%02td (%p) -> (%td) : ",
81  statement_number(s),
82  s,
84 
85  MAP(EFFECT, e, {
86  print_words(stderr, words_effect(e));
87  fprintf(stderr, "(%p), ", e);
88  }, effects_effects(e));
89 
90  fprintf(stderr, "\n");
91  }, se);
92 }
list words_effect(effect)
#define STATEMENT_EFFECTS_MAP(k, v, c, f)
Definition: effects.h:1057
#define effects_effects(x)
Definition: effects.h:710
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
size_t gen_length(const list l)
Definition: list.c:150
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
void print_words(FILE *fd, cons *lw)
Definition: print.c:263

References EFFECT, effects_effects, fprintf(), gen_length(), MAP, print_words(), STATEMENT_EFFECTS_MAP, statement_number, and words_effect().

+ Here is the call graph for this function:

◆ find_level_l_loop_statement()

statement find_level_l_loop_statement ( scc  s,
int  l 
)

s is a strongly connected component which is analyzed at level l.

Its vertices are enclosed in at least l loops. This gives us a solution to retrieve the level l loop enclosing a scc: to take its first vertex and retrieve the l-th loop around this vertex.

Definition at line 213 of file codegen.c.

213  {
214  vertex v = VERTEX(CAR(scc_vertices(s)));
217 
218  if(l > 0)
219  MAPL(pl, {
220  if (l-- == 1)
221  return(STATEMENT(CAR(pl)));
222  }, loops);
223  return (statement_undefined);
224 }
static list loops
#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
static hash_table pl
properties are stored in this hash table (string -> property) for fast accesses.
Definition: properties.c:783
list load_statement_enclosing_loops(statement)
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References CAR, load_statement_enclosing_loops(), loops, MAPL, pl, scc_vertices, STATEMENT, statement_undefined, VERTEX, and vertex_to_statement().

Referenced by ConnectedStatements().

+ Here is the call graph for this function:
+ 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
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

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
#define sccflags_mark(x)
Definition: dg.h:275
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
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
#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

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:

◆ ignore_this_conflict()

bool ignore_this_conflict ( vertex  v1,
vertex  v2,
conflict  c,
int  l 
)

codegen.c

codegen.c

A conflict is to be ignored if the variable that creates the conflict is local to one of the enclosing loops.

FI: this should be extended to variables declared within the last loop body for C code?

Note: The loops around every statement got by load_statement_loops(statement) here are just these after taking off the loops on which the Kennedy's algo. can't be applied. (YY)

FI: I do not understand the note above.

equivalences do not deserve more cpu cycles

Parameters
v11
v22

Definition at line 163 of file codegen.c.

163  {
164  extern int enclosing;
165  effect e1 = conflict_source(c);
167  entity var1 = reference_variable(r1);
170 
171  effect e2 = conflict_sink(c);
172  reference r2 = effect_any_reference( e2 );
173  entity var2 = reference_variable(r2);
176  register int i;
177 
178  if(var1 != var2) {
179  /* equivalences do not deserve more cpu cycles */
180  return (false);
181  }
182  for (i = 1; i < l - enclosing; i++) {
183  if(!ENDP(loops1)) {
184  loops1 = CDR(loops1);
185  }
186  if(!ENDP(loops2)) {
187  loops2 = CDR(loops2);
188  }
189  }
190  ifdebug(8) {
191  pips_debug(8, "verifying the following conflit at level %d: \n",l);
192  fprintf(stderr,
193  "\t%02td --> %02td ",
195  statement_number(s2));
196  fprintf(stderr, "\t\tfrom ");
198 
199  fprintf(stderr, " to ");
201  fprintf(stderr, "\n");
202  }
203 
204  return variable_private_to_loop_p(loops1, var1)
205  || variable_private_to_loop_p(loops2, var2);
206 }
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define reference_variable(x)
Definition: ri.h:2326
static bool variable_private_to_loop_p(list loops, entity var)
Check if a variable is private to loop nest.
Definition: codegen.c:113

References CDR, conflict_sink, conflict_source, effect_any_reference, enclosing, ENDP, fprintf(), ifdebug, load_statement_enclosing_loops(), pips_debug, print_effect, reference_variable, s1, statement_number, variable_private_to_loop_p(), and vertex_to_statement().

Referenced by contains_level_l_dependence(), prettyprint_dependence_graph_view(), prettyprint_dot_dependence_graph(), and search_parallel_loops().

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

◆ invariant_code_motion()

bool invariant_code_motion ( const char *  module_name)

Phase that hoists loop invariant code out of loops.

Parameters
[in]module_name
Returns
true because everything should go fine

Prepare some stuffs and call icm_codegen...

Parameters
module_nameodule_name

Definition at line 1495 of file icm.c.

1496 {
1500 
1501  set_bool_property( "GENERATE_NESTED_PARALLEL_LOOPS", true );
1502  set_bool_property( "RICE_DATAFLOW_DEPENDENCE_ONLY", false );
1503 
1505  db_get_memory_resource(DBR_CODE,
1506  module_name,
1507  true));
1508 
1510 
1512 
1513  debug_on("ICM_DEBUG_LEVEL");
1514 
1515  ifdebug(7)
1516  {
1517  fprintf(stderr,
1518  "\nTesting NewGen consistency for initial code %s:\n",
1519  module_name);
1521  fprintf(stderr," NewGen consistent statement\n");
1522  }
1523 
1524  ifdebug(1) {
1525  pips_debug(1, "original sequential code:\n\n");
1527  }
1528 
1529  if (graph_undefined_p(dg)) {
1530  dg = (graph) db_get_memory_resource(DBR_DG, module_name, true);
1531  }
1532  else {
1533  pips_internal_error("dg should be undefined");
1534  }
1535 
1536  enclosing = 0;
1538 
1539  ifdebug(7) {
1540  fprintf(stderr, "\ntransformed code %s:",module_name);
1542  fprintf(stderr," gen consistent ");
1543  }
1544 
1545  // Uselessly reinitialize ordering_to_statement, even if it not set...
1548 
1550 
1551  dg = graph_undefined;
1555 
1556  debug_off();
1557  return true;
1558 }
static graph dg
dg is the dependency graph ; FIXME : should not be static global ?
Definition: chains.c:124
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
static statement icm_codegen(statement stat, graph g, set region, int level, bool task_parallelize_p)
Definition: icm.c:1382
void set_bool_property(const char *, bool)
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244

References clean_up_sequences(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, dg, enclosing, fprintf(), get_current_module_statement(), graph_undefined, graph_undefined_p, icm_codegen(), ifdebug, local_name_to_top_level_entity(), mod_stat, module, module_name(), module_reorder(), pips_debug, pips_internal_error, print_statement(), reset_current_module_entity(), reset_current_module_statement(), reset_ordering_to_statement(), rice_statement(), set_bool_property(), set_current_module_entity(), set_current_module_statement(), set_ordering_to_statement(), statement_consistent_p(), and statement_undefined.

+ Here is the call 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:

◆ IsolatedStatement()

statement IsolatedStatement ( scc  s,
int  l,
bool  task_parallelize_p 
)

If the isolated statement is a CALL and is not a CONTINUE, regenerate the nested loops around it.

Otherwise, returns an undefined statement.

continue statements are ignored.

I: But they should not be isolated statements if the contain declarations...

FI: we are likely to end up in trouble here because C allows expressions as instructions...

FI: if the statement is any kind of loop or a test, do not go down.

Parameters
task_parallelize_pask_parallelize_p

Definition at line 571 of file codegen.c.

571  {
572  vertex v = VERTEX(CAR(scc_vertices(s)));
577  extern int enclosing;
578 
579  pips_debug(8, "Input statement %" PRIdPTR "\n", statement_number(st));
580 
581  /* continue statements are ignored. */
582  /*FI: But they should not be isolated statements if the contain
583  declarations... */
584  //if(declaration_statement_p(st))
585  //pips_internal_error("Declaration statement is junked.");
586 
587  if(!instruction_call_p(sbody) || (continue_statement_p(st)
588  && !declaration_statement_p(st)))
589  ;
590  /* FI: we are likely to end up in trouble here because C allows
591  expressions as instructions... */
592  /* FI: if the statement is any kind of loop or a test, do not go
593  down.*/
594  else
595  rst = MakeNestOfParallelLoops(l - 1 - enclosing,
596  loops,
597  st,
598  task_parallelize_p);
599 
600  ifdebug(8) {
601  pips_debug(8, "Returned statement:\n");
603  }
604 
605  return (rst);
606 }
bool continue_statement_p(statement)
Test if a statement is a CONTINUE, that is the FORTRAN nop, the ";" in C or the "pass" in Python....
Definition: statement.c:203
bool declaration_statement_p(statement)
Had to be optimized according to Beatrice Creusillet.
Definition: statement.c:224
void safe_print_statement(statement)
Definition: statement.c:140
#define instruction_call_p(x)
Definition: ri.h:1527
#define statement_instruction(x)
Definition: ri.h:2458
statement MakeNestOfParallelLoops(int l, cons *loops, statement body, bool task_parallelize_p)
this function creates a nest of parallel loops around an isolated statement whose iterations may exec...
Definition: codegen.c:310

References CAR, continue_statement_p(), declaration_statement_p(), enclosing, ifdebug, instruction_call_p, load_statement_enclosing_loops(), loops, MakeNestOfParallelLoops(), pips_debug, safe_print_statement(), scc_vertices, statement_instruction, statement_number, statement_undefined, VERTEX, and vertex_to_statement().

Referenced by CodeGenerate().

+ Here is the call graph for this function:
+ 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_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
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:

◆ MakeLoopAs()

statement MakeLoopAs ( statement  old_loop_statement,
tag  seq_or_par,
statement  body 
)

This function creates a new loop whose characteristics (index, bounds, ...) are similar to those of old_loop.

The body and the execution type are different between the old and the new loop.

fixed bug about private variable without effects, FC 22/09/93

avoid sharing

Parameters
old_loop_statementld_loop_statement
seq_or_pareq_or_par
bodyody

Definition at line 517 of file codegen.c.

519  {
520  loop old_loop = statement_loop(old_loop_statement);
521  loop new_loop;
522  statement new_loop_s;
523  statement old_body = loop_body (old_loop);
524  list new_locals = gen_copy_seq(loop_locals(old_loop));
525 
527  seq_or_par = is_execution_sequential;
528 
529  // copy declaration from old body to new body
530  if((statement_decls_text (old_body) != string_undefined)
531  && (statement_decls_text (old_body) != NULL)) {
532  if(!statement_block_p(body))
533  body = make_block_statement(CONS(STATEMENT,body,NIL));
535  }
536  if((statement_declarations (old_body) != list_undefined)
537  && (statement_declarations (old_body) != NULL)) {
538  if(!statement_block_p(body))
539  body = make_block_statement(CONS(STATEMENT,body,NIL));
541  = gen_copy_seq(statement_declarations (old_body));
542  }
543 
544  new_loop = make_loop(loop_index(old_loop), copy_range(loop_range(old_loop)), /* avoid sharing */
545  body, entity_empty_label(), make_execution(seq_or_par, UU), new_locals);
546 
547  new_loop_s
549  statement_number(old_loop_statement),
553  NIL,
554  NULL,
556 
557  ifdebug(8) {
558  pips_assert("Execution is either parallel or sequential",
559  seq_or_par==is_execution_sequential || seq_or_par==is_execution_parallel);
560  pips_debug(8, "New %s loop\n",
561  seq_or_par==is_execution_sequential? "sequential" : "parallel");
562  print_parallel_statement(new_loop_s);
563  }
564 
565  return (new_loop_s);
566 }
execution make_execution(enum execution_utype tag, void *val)
Definition: ri.c:838
range copy_range(range p)
RANGE.
Definition: ri.c:2005
loop make_loop(entity a1, range a2, statement a3, entity a4, execution a5, list a6)
Definition: ri.c:1301
statement make_statement(entity a1, intptr_t a2, intptr_t a3, string a4, instruction a5, list a6, string a7, extensions a8, synchronization a9)
Definition: ri.c:2222
instruction make_instruction(enum instruction_utype tag, void *val)
Definition: ri.c:1166
synchronization make_synchronization_none(void)
Definition: ri.c:2424
extensions copy_extensions(extensions p)
EXTENSIONS.
Definition: ri.c:947
statement make_block_statement(list)
Make a block statement from a list of statement.
Definition: statement.c:616
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define STATEMENT_ORDERING_UNDEFINED
mapping.h inclusion
Definition: newgen-local.h:35
#define string_undefined
Definition: newgen_types.h:40
#define copy_string(s)
Definition: newgen_types.h:42
#define UU
Definition: newgen_types.h:98
#define statement_block_p(stat)
entity entity_empty_label(void)
Definition: entity.c:1105
#define loop_body(x)
Definition: ri.h:1644
@ is_instruction_loop
Definition: ri.h:1471
#define statement_extensions(x)
Definition: ri.h:2464
#define loop_locals(x)
Definition: ri.h:1650
#define statement_declarations(x)
Definition: ri.h:2460
#define statement_decls_text(x)
Definition: ri.h:2462
#define loop_range(x)
Definition: ri.h:1642
#define loop_index(x)
Definition: ri.h:1640
bool rice_distribute_only
to know if do loop parallelization must be done
Definition: rice.h:53

References CONS, copy_extensions(), copy_range(), copy_string, entity_empty_label(), gen_copy_seq(), ifdebug, is_execution_parallel, is_execution_sequential, is_instruction_loop, list_undefined, loop_body, loop_index, loop_locals, loop_range, make_block_statement(), make_execution(), make_instruction(), make_loop(), make_statement(), make_synchronization_none(), NIL, pips_assert, pips_debug, print_parallel_statement(), rice_distribute_only, STATEMENT, statement_block_p, statement_declarations, statement_decls_text, statement_extensions, statement_loop(), statement_number, STATEMENT_ORDERING_UNDEFINED, string_undefined, and UU.

Referenced by ConnectedStatements(), and MakeNestOfParallelLoops().

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

◆ MakeNestOfParallelLoops()

statement MakeNestOfParallelLoops ( int  l,
cons loops,
statement  body,
bool  task_parallelize_p 
)

this function creates a nest of parallel loops around an isolated statement whose iterations may execute in parallel.

loops is the loop nest that was around body in the original program. l is the current level; it tells us how many loops have already been processed.

At most one outer loop parallel

Parameters
loopsoops
bodyody
task_parallelize_pask_parallelize_p

Definition at line 310 of file codegen.c.

313  {
314  statement s;
315  pips_debug(3, " at level %d ...\n",l);
316 
317  if(loops == NIL)
318  s = body;
319  else if(l > 0)
320  s = MakeNestOfParallelLoops(l - 1, CDR(loops), body, task_parallelize_p);
321  else {
322  statement slo = STATEMENT(CAR(loops));
323  loop lo = statement_loop(slo);
324  tag seq_or_par = ((CDR(loops) == NIL || task_parallelize_p)
327 
328  /* At most one outer loop parallel */
329  bool
330  task_parallelize_inner =
331  (seq_or_par == is_execution_parallel
332  && !get_bool_property("GENERATE_NESTED_PARALLEL_LOOPS")) ? false
333  : task_parallelize_p;
334 
335  s = MakeLoopAs(slo,
336  seq_or_par,
338  CDR(loops),
339  body,
340  task_parallelize_inner));
341  }
342  return (s);
343 }

References CAR, CDR, get_bool_property(), index_private_p(), is_execution_parallel, is_execution_sequential, loops, MakeLoopAs(), NIL, pips_debug, STATEMENT, and statement_loop().

Referenced by IsolatedStatement(), and MakeNestOfStatementList().

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

◆ MakeNestOfStatementList()

statement MakeNestOfStatementList ( int  l,
int  nbl,
list lst,
list  loops,
list block,
list eblock,
bool  task_parallelize_p 
)
Parameters
nblbl
lstst
loopsoops
blocklock
eblockblock
task_parallelize_pask_parallelize_p

Definition at line 350 of file codegen.c.

356  {
359  extern int enclosing;
360 
361  debug_on("RICE_DEBUG_LEVEL");
362 
363  if(*lst != NIL && nbl) {
364  if(gen_length(*lst) == 1)
365  rst = (STATEMENT(CAR(*lst)));
366  else
367  rst = make_block_statement(*lst);
368  if(nbl >= l - 1)
369  stat = MakeNestOfParallelLoops(l - 1 - enclosing,
370  loops,
371  rst,
372  task_parallelize_p);
373  else
374  stat = rst;
375  *lst = NIL;
376  INSERT_AT_END(*block, *eblock, CONS(STATEMENT, stat, NIL));
377  }
378 
379  debug_off();
380  return (stat);
381 }
#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, CONS, debug_off, debug_on, enclosing, gen_length(), INSERT_AT_END, loops, make_block_statement(), MakeNestOfParallelLoops(), NIL, STATEMENT, and statement_undefined.

Referenced by CodeGenerate().

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

◆ print_list_entities()

void print_list_entities ( list  l)
Parameters
lof entity

Definition at line 151 of file icm.c.

152 {
153  MAP(ENTITY, e, {
154  fprintf(stderr, "%s ", entity_name(e));
155  }, l);
156 }
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define entity_name(x)
Definition: ri.h:2790

References ENTITY, entity_name, fprintf(), and MAP.

Referenced by statement_depend_of_indices_p().

+ 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 }

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 }
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 }

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:

◆ rice_all_dependence()

bool rice_all_dependence ( string  mod_name)
Parameters
mod_nameod_name

Definition at line 400 of file rice.c.

400  {
401  set_bool_property("GENERATE_NESTED_PARALLEL_LOOPS", true);
402  set_bool_property("RICE_DATAFLOW_DEPENDENCE_ONLY", false);
403  return rice(mod_name);
404 }
static bool rice(string mod_name)
Definition: rice.c:380

References rice(), and set_bool_property().

+ Here is the call graph for this function:

◆ rice_cray()

bool rice_cray ( string  mod_name)
Parameters
mod_nameod_name

Definition at line 413 of file rice.c.

413  {
414  set_bool_property("GENERATE_NESTED_PARALLEL_LOOPS", false);
415  set_bool_property("RICE_DATAFLOW_DEPENDENCE_ONLY", false);
416  return rice(mod_name);
417 }

References rice(), and set_bool_property().

+ Here is the call graph for this function:

◆ rice_data_dependence()

bool rice_data_dependence ( string  mod_name)
Parameters
mod_nameod_name

Definition at line 406 of file rice.c.

406  {
407  set_bool_property("GENERATE_NESTED_PARALLEL_LOOPS", true);
408  set_bool_property("RICE_DATAFLOW_DEPENDENCE_ONLY", true);
409  pips_user_warning("This phase is designed for experimental purposes only. The generated code is most likely to be illegal, especially if a privatization phase was performed before.\n");
410  return rice(mod_name);
411 }

References pips_user_warning, rice(), and set_bool_property().

+ Here is the call graph for this function:

◆ rice_loop()

statement rice_loop ( statement  stat,
int  l,
statement(*)(statement, graph, set, int, bool codegen_fun 
)

Eventually parallelize a do-loop with à la Rice algorithm.

Returns
a statement with the same loop (not parallelized), a statement with a parallelized do-loop or an empty statement (the loop body was empty so it is trivially parallelized in this way).

Well the loop is already parallel and we are asked not to do the job again that may lead to less optimal code for the target:

The code generation did not generate anything, probably because the loop body was empty ("CONTINUE"/";", "{ }"), so no loop is generated:

FI: I'd rather not return a block when a unique loop statement has to be wrapped.

try to keep label

Do not forget to move forbidden information associated with block:

StatementToContext should be freed here. but it is not easy.

Skip the parallelization of this loop but go on recursion for eventual loops in this loop body:

Parameters
stattat

Definition at line 160 of file rice.c.

162  {
163  statement nstat;
164  instruction istat = statement_instruction(stat);
165  loop lstat = instruction_loop(istat);
166  set region;
167  //statement b = statement_undefined;
168  ifdebug(1) {
169  pips_debug(1, "original nest of loops:\n\n");
170  print_statement(stat);
171  }
172 
173  if((region = distributable_loop(stat)) == set_undefined) {
174  int so = statement_ordering(stat);
175  user_warning("rice_loop",
176  "Cannot apply Allen & Kennedy's algorithm on "
177  "loop %s with index %s at Statement %d (%d, %d)"
178  " because it contains either tests or goto statements"
179  " which prohibit loop distribution. You could activate the"
180  " coarse_grain_parallelization rule.\n",
183  statement_number(stat),
184  ORDERING_NUMBER(so),
185  ORDERING_STATEMENT(so));
186  goto skip_parallelization_of_this_loop;
187  }
188 
189  if(!get_bool_property("PARALLELIZE_AGAIN_PARALLEL_CODE")
190  && parallel_loop_statement_p(stat))
191  /* Well the loop is already parallel and we are asked not to do the
192  job again that may lead to less optimal code for the target: */
193  goto skip_parallelization_of_this_loop;
194 
195  ifdebug(2) {
196  debug(2, "rice_loop", "applied on region:\n");
197  print_statement_set(stderr, region);
198  }
199 
201  nstat = codegen_fun(stat, dg, region, l, true);
202 
203  ifdebug(7) {
204  pips_debug(7, "consistency checking for CodeGenerate output: ");
205  if(statement_consistent_p(nstat))
206  fprintf(stderr, " gen consistent\n");
207  }
208 
209  if(nstat == statement_undefined)
210  /* The code generation did not generate anything, probably because the
211  loop body was empty ("CONTINUE"/";", "{ }"), so no loop is
212  generated: */
213  nstat = make_empty_statement();
214 
215  /* FI: I'd rather not return a block when a unique loop statement has to
216  * be wrapped.
217  */pips_assert("block or loop",
220  /* try to keep label */
221  if(statement_loop_p(nstat))
222  statement_label(nstat) = statement_label(stat);
223  else {
225  if(statement_loop_p(s)) {
226  statement_label(s) = statement_label(stat);
227  break;
228  }
229  }
230  statement_number(nstat)
232  : statement_number(stat));
233  statement_ordering(nstat) = statement_ordering(stat);
234  statement_comments(nstat) = statement_comments(stat);
235  /* Do not forget to move forbidden information associated with
236  block: */
238  ifdebug(1) {
239  fprintf(stderr, "final nest of loops:\n\n");
241  }
242 
243  /* StatementToContext should be freed here. but it is not easy. */
244  set_free(region);
245 
247 
248  return nstat;
249 
250  /* Skip the parallelization of this loop but go on recursion for
251  eventual loops in this loop body: */
252  skip_parallelization_of_this_loop: enclosing++;
253  loop_body(lstat) = rice_statement(loop_body(lstat), l + 1, codegen_fun);
254  enclosing--;
255  return (stat);
256 }
set distributable_loop(statement l)
this functions checks if Kennedy's algorithm can be applied on the loop passed as argument.
Definition: loop.c:221
bool parallel_loop_statement_p(statement s)
Test if a statement is a parallel loop.
Definition: loop.c:420
void clean_enclosing_loops(void)
Definition: loop.c:58
statement_mapping loops_mapping_of_statement(statement stat)
Definition: loop.c:155
list statement_block(statement)
Get the list of block statements of a statement sequence.
Definition: statement.c:1338
bool statement_loop_p(statement)
Definition: statement.c:349
void fix_statement_attributes_if_sequence(statement)
Apply fix_sequence_statement_attributes() on the statement only if it really a sequence.
Definition: statement.c:2078
#define user_warning(fn,...)
Definition: misc-local.h:262
#define set_undefined
Definition: newgen_set.h:48
void print_statement_set(FILE *, set)
statement.c
Definition: statement.c:49
#define instruction_block_p(i)
#define ORDERING_NUMBER(o)
#define ORDERING_STATEMENT(o)
#define STATEMENT_NUMBER_UNDEFINED
default values
#define make_empty_statement
An alias for make_empty_block_statement.
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
const char * label_local_name(entity e)
END_EOLE.
Definition: entity.c:604
void set_enclosing_loops_map(statement_mapping)
#define instruction_loop_p(x)
Definition: ri.h:1518
#define instruction_loop(x)
Definition: ri.h:1520
#define statement_ordering(x)
Definition: ri.h:2454
#define statement_label(x)
Definition: ri.h:2450
#define loop_label(x)
Definition: ri.h:1646
#define statement_comments(x)
Definition: ri.h:2456

References clean_enclosing_loops(), debug(), dg, distributable_loop(), enclosing, entity_local_name(), fix_statement_attributes_if_sequence(), FOREACH, fprintf(), get_bool_property(), ifdebug, instruction_block_p, instruction_loop, instruction_loop_p, label_local_name(), loop_body, loop_index, loop_label, loops_mapping_of_statement(), make_empty_statement, ORDERING_NUMBER, ORDERING_STATEMENT, parallel_loop_statement_p(), pips_assert, pips_debug, print_parallel_statement(), print_statement(), print_statement_set(), region, rice_statement(), set_enclosing_loops_map(), set_free(), set_undefined, STATEMENT, statement_block(), statement_block_p, statement_comments, statement_consistent_p(), statement_instruction, statement_label, statement_loop_p(), statement_number, STATEMENT_NUMBER_UNDEFINED, statement_ordering, statement_undefined, and user_warning.

Referenced by rice_statement().

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

◆ rice_statement()

statement rice_statement ( statement  stat,
int  l,
statement(*)(statement, graph, set, int, bool codegen_fun 
)
Parameters
stattat

Definition at line 82 of file rice.c.

88  {
89  instruction istat = statement_instruction(stat);
90  statement new_stat = stat; // Most statements are modified by side effects
91 
92  switch(instruction_tag(istat)) {
93  case is_instruction_block: {
94  MAPL(pc, {
95  statement st = STATEMENT(CAR(pc));
96  STATEMENT_(CAR(pc)) = rice_statement(st,l,codegen_fun);
97  }, instruction_block(istat));
98  break;
99  }
100  case is_instruction_test: {
101  test obj_test = instruction_test(istat);
102  test_true(obj_test) = rice_statement(test_true(obj_test), l, codegen_fun);
103  test_false(obj_test) = rice_statement(test_false(obj_test),
104  l,
105  codegen_fun);
106  break;
107  }
108  case is_instruction_loop: {
109  new_stat = rice_loop(stat, l, codegen_fun);
110  ifdebug(7) {
111  if(statement_loop_p(new_stat))
112  pips_debug(7, "regenerated loop is %s:",
114  "sequential" : "parallel");
115  else
116  pips_debug(7, "regenerated code:");
117  if(statement_consistent_p(new_stat))
118  fprintf(stderr, " consistent\n");
119  print_parallel_statement(new_stat);
120  }
121  break;
122  }
124  whileloop wl = instruction_whileloop(istat);
125 
126  whileloop_body(wl) = rice_statement(whileloop_body(wl), l, codegen_fun);
127  break;
128  }
129  case is_instruction_forloop: {
130  forloop wl = instruction_forloop(istat);
131 
132  forloop_body(wl) = rice_statement(forloop_body(wl), l, codegen_fun);
133  break;
134  }
135  case is_instruction_goto:
136  pips_internal_error("Unexpected go to instruction in parsed code");
137  break;
138  case is_instruction_call:
140  break;
142  unstructured obj_unstructured = instruction_unstructured(istat);
143  rice_unstructured(obj_unstructured, l, codegen_fun);
144  break;
145  }
146  default:
147  pips_internal_error("default case reached with tag %d",
148  instruction_tag(istat));
149  }
150 
151  return (new_stat);
152 }
#define is_instruction_block
soft block->sequence transition
#define instruction_block(i)
#define STATEMENT_(x)
Definition: ri.h:2416
#define loop_execution(x)
Definition: ri.h:1648
#define test_false(x)
Definition: ri.h:2837
@ is_instruction_goto
Definition: ri.h:1473
@ is_instruction_unstructured
Definition: ri.h:1475
@ is_instruction_whileloop
Definition: ri.h:1472
@ is_instruction_expression
Definition: ri.h:1478
@ is_instruction_test
Definition: ri.h:1470
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_forloop
Definition: ri.h:1477
#define instruction_tag(x)
Definition: ri.h:1511
#define execution_sequential_p(x)
Definition: ri.h:1208
#define test_true(x)
Definition: ri.h:2835
#define instruction_forloop(x)
Definition: ri.h:1538
#define instruction_whileloop(x)
Definition: ri.h:1523
#define whileloop_body(x)
Definition: ri.h:3162
#define instruction_test(x)
Definition: ri.h:1517
#define forloop_body(x)
Definition: ri.h:1372
#define instruction_unstructured(x)
Definition: ri.h:1532
statement rice_loop(statement stat, int l, statement(*codegen_fun)(statement, graph, set, int, bool))
Eventually parallelize a do-loop with Ã&#160; la Rice algorithm.
Definition: rice.c:160
void rice_unstructured(unstructured u, int l, statement(*codegen_fun)(statement, graph, set, int, bool))
Definition: rice.c:69

References CAR, execution_sequential_p, forloop_body, fprintf(), ifdebug, instruction_block, instruction_forloop, instruction_loop, instruction_tag, instruction_test, instruction_unstructured, instruction_whileloop, is_instruction_block, is_instruction_call, is_instruction_expression, is_instruction_forloop, is_instruction_goto, is_instruction_loop, is_instruction_test, is_instruction_unstructured, is_instruction_whileloop, loop_execution, MAPL, pips_debug, pips_internal_error, print_parallel_statement(), rice_loop(), rice_unstructured(), STATEMENT, STATEMENT_, statement_consistent_p(), statement_instruction, statement_loop_p(), test_false, test_true, and whileloop_body.

Referenced by do_it(), invariant_code_motion(), rice_loop(), and rice_unstructured().

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

◆ rice_unstructured()

void rice_unstructured ( unstructured  u,
int  l,
statement(*)(statement, graph, set, int, bool codegen_fun 
)

Definition at line 69 of file rice.c.

71  {
72  cons *blocs = NIL;
73 
74  CONTROL_MAP(c, {
75  statement st = rice_statement(control_statement(c),l,codegen_fun);
76  control_statement(c) = st;
77  }, unstructured_control(u), blocs);
78 
79  gen_free_list(blocs);
80 }
#define CONTROL_MAP(ctl, code, c, list)
Macro to walk through all the controls reachable from a given control node of an unstructured.
#define unstructured_control
After the modification in Newgen: unstructured = entry:control x exit:control we have create a macro ...
#define control_statement(x)
Definition: ri.h:941

References CONTROL_MAP, control_statement, gen_free_list(), NIL, rice_statement(), and unstructured_control.

Referenced by rice_statement().

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

◆ scc_region()

set scc_region ( scc  s)

Definition at line 226 of file codegen.c.

226  {
228  MAPL(pv, {
230  (char *) vertex_to_statement(VERTEX(CAR(pv))));
231  }, scc_vertices(s));
232  return (region);
233 }
@ set_pointer
Definition: newgen_set.h:44
set set_make(set_type)
Create an empty set of any type but hash_private.
Definition: set.c:102
set set_add_element(set, const set, const void *)
Definition: set.c:152

References CAR, MAPL, region, scc_vertices, set_add_element(), set_make(), set_pointer, VERTEX, and vertex_to_statement().

Referenced by ConnectedStatements().

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

◆ set_sccs_drivers()

void set_sccs_drivers ( bool(*)(set, vertex ,
bool(*)(vertex, set, successor, int  
)

scc.c

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

+ Here is the caller graph for this function:

◆ statement_imbrication_level()

int statement_imbrication_level ( statement  st)
Parameters
stt

Definition at line 345 of file codegen.c.

345  {
347  return (gen_length(loops));
348 }

References gen_length(), load_statement_enclosing_loops(), and loops.

+ Here is the call graph for this function:

◆ strongly_connected_p()

bool strongly_connected_p ( scc  s,
int  l 
)

this function returns true if scc s is stronly connected at level l, i.e.

dependence arcs at level l or greater form at least one cycle

if s contains more than one vertex, it is strongly connected

if there is a dependence from v to v, s is strongly connected

s is not strongly connected

Definition at line 284 of file codegen.c.

284  {
285  cons *pv = scc_vertices(s);
286  vertex v = VERTEX(CAR(pv));
287 
288  /* if s contains more than one vertex, it is strongly connected */
289  if(CDR(pv) != NIL)
290  return (true);
291  /* if there is a dependence from v to v, s is strongly connected */
294  && successor_vertex(s) == v)
295  return (true);
296  }
297 
298  /* s is not strongly connected */
299  return (false);
300 }
static bool AK_ignore_this_level(dg_arc_label dal, int level)
Definition: codegen.c:43

References AK_ignore_this_level(), CAR, CDR, FOREACH, NIL, scc_vertices, SUCCESSOR, successor_arc_label, successor_vertex, VERTEX, and vertex_successors.

Referenced by CodeGenerate(), and SimplifyGraph().

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

◆ TopSortSccs()

list TopSortSccs ( graph  ,
set  ,
int  ,
sccs   
)

Variable Documentation

◆ dg

graph dg
extern

external variables.

cproto-generated files

see declarations in kennedy.c

rice.c

external variables.

Modifications:

  • Bruno Baron:
  • Francois Irigoin: I do not understand why regions of statements are implemented as set of statements instead of set of statement orderings since the dependence graph refers to statement orderings.
  • Francois Irigoin: use a copy of the code statement to generate the parallel code, instead of using side effects on the sequential code statement. This works because the dependence graph uses persistent pointers towards statement, statement_ordeging, and because the references are the same in the sequential code and in its copy. So references are still accessible, although it may be useless for parallelization. FI: I want misc.h and I end up with the other ones as well? the dependence graph of the current loop nest

Definition at line 52 of file rice.h.

Referenced by do_it(), and rice_loop().

◆ enclosing

int enclosing
extern

This is an horrendous hack.

ENCLOSING should be passed as an argument, but I don't have the courage to make the changes .

Definition at line 67 of file rice.c.

Referenced by ConnectedStatements(), do_it(), glc_call(), glc_cast(), glc_ref(), ignore_this_conflict(), invariant_code_motion(), IsolatedStatement(), MakeNestOfStatementList(), and rice_loop().

◆ Nbrdoall

int Nbrdoall
extern

◆ rice_distribute_only

bool rice_distribute_only
extern

to know if do loop parallelization must be done

Definition at line 53 of file rice.h.

Referenced by do_it().