PIPS
codegen.c File Reference
#include "local.h"
#include "prettyprint.h"
#include "effects-generic.h"
+ Include dependency graph for codegen.c:

Go to the source code of this file.

Functions

static bool AK_ignore_this_level (dg_arc_label dal, int level)
 
static bool AK_ignore_this_vertex (set region, vertex v)
 
static bool AK_ignore_this_successor (vertex __attribute__((unused)) v, set region, successor su, int level)
 
static bool variable_private_to_loop_p (list loops, entity var)
 Check if a variable is private to loop nest. More...
 
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. More...
 
statement find_level_l_loop_statement (scc s, int l)
 s is a strongly connected component which is analyzed at level l. More...
 
set scc_region (scc s)
 
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. More...
 
bool strongly_connected_p (scc s, int l)
 this function returns true if scc s is stronly connected at level l, i.e. More...
 
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. More...
 
int statement_imbrication_level (statement st)
 
statement MakeNestOfStatementList (int l, int nbl, list *lst, list loops, list *block, list *eblock, bool task_parallelize_p)
 
statement CodeGenerate (statement __attribute__((unused)) stat, graph g, set region, int l, bool task_parallelize_p)
 This function implements Allen & Kennedy's algorithm. More...
 
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. More...
 
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. More...
 
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. More...
 

Variables

entity current_module_entity
 FI: I did not know this was still used... More...
 

Function Documentation

◆ AK_ignore_this_level()

static bool AK_ignore_this_level ( dg_arc_label  dal,
int  level 
)
static

Definition at line 43 of file codegen.c.

43  {
44  bool true_dep = get_bool_property("RICE_DATAFLOW_DEPENDENCE_ONLY");
46  if(conflict_cone(c) != cone_undefined) {
47  FOREACH(int, l, cone_levels(conflict_cone(c)))
48  {
49  if(l >= level) {
50  if(true_dep) {
53 
54  return (action_write_p( s ) && action_read_p( k ));
55  } else {
56  return (false);
57  }
58  }
59  }
60  }
61  }
62 
63  return (true);
64 }
#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 conflict_source(x)
Definition: dg.h:165
#define cone_undefined
Definition: dg.h:104
#define conflict_cone(x)
Definition: dg.h:169
#define effect_action(x)
Definition: effects.h:642
#define action_write_p(x)
Definition: effects.h:314
#define action_read_p(x)
Definition: effects.h:311
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#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 level

References action_read_p, action_write_p, cone_levels, cone_undefined, CONFLICT, conflict_cone, conflict_sink, conflict_source, dg_arc_label_conflicts, effect_action, FOREACH, get_bool_property(), and level.

Referenced by AK_ignore_this_successor(), and strongly_connected_p().

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

◆ AK_ignore_this_successor()

static bool AK_ignore_this_successor ( vertex __attribute__((unused))  v,
set  region,
successor  su,
int  level 
)
static

Definition at line 82 of file codegen.c.

85  {
87 
88  bool ignore_p = AK_ignore_this_vertex(region, successor_vertex(su));
89 
90  if(!ignore_p)
91  ignore_p = AK_ignore_this_level(al, level);
92 
93  if(!ignore_p
94  && get_bool_property("PARALLELIZATION_IGNORE_THREAD_SAFE_VARIABLES")) {
96  bool thread_safe_p = true;
97  FOREACH(CONFLICT, c, cl) {
98  effect e = conflict_source(c);
100  entity v = reference_variable(r);
101 
102  if(!thread_safe_variable_p(v)) {
103  thread_safe_p = false;
104  break;
105  }
106  }
107  ignore_p = thread_safe_p;
108  }
109  return ignore_p;
110 }
struct _newgen_struct_dg_arc_label_ * dg_arc_label
Definition: dg.h:60
#define region
simulation of the type region
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define successor_vertex(x)
Definition: graph.h:118
#define successor_arc_label(x)
Definition: graph.h:116
bool thread_safe_variable_p(entity v)
Definition: entity.c:2539
#define reference_variable(x)
Definition: ri.h:2326
static bool AK_ignore_this_vertex(set region, vertex v)
Definition: codegen.c:70
static bool AK_ignore_this_level(dg_arc_label dal, int level)
Definition: codegen.c:43
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References AK_ignore_this_level(), AK_ignore_this_vertex(), CONFLICT, conflict_source, dg_arc_label_conflicts, effect_any_reference, FOREACH, get_bool_property(), level, reference_variable, region, successor_arc_label, successor_vertex, and thread_safe_variable_p().

Referenced by CodeGenerate().

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

◆ AK_ignore_this_vertex()

static bool AK_ignore_this_vertex ( set  region,
vertex  v 
)
static

Definition at line 70 of file codegen.c.

70  {
73 
74  return (!set_belong_p(region, (char *)st));
75 }
#define dg_vertex_label_statement(x)
Definition: dg.h:235
struct _newgen_struct_dg_vertex_label_ * dg_vertex_label
Definition: dg.h:68
#define vertex_vertex_label(x)
Definition: graph.h:152
bool set_belong_p(const set, const void *)
Definition: set.c:194
statement ordering_to_statement(int o)
Get the statement associated to a given ordering.
Definition: ordering.c:111

References dg_vertex_label_statement, ordering_to_statement(), region, set_belong_p(), and vertex_vertex_label.

Referenced by AK_ignore_this_successor(), CodeGenerate(), and contains_level_l_dependence().

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

◆ CodeGenerate()

statement CodeGenerate ( statement __attribute__((unused))  stat,
graph  g,
set  region,
int  l,
bool  task_parallelize_p 
)

This function implements Allen & Kennedy's algorithm.

BB (Bruno Baron): task_parallelize_p is true when we want to parallelize the loop, false when we only want to vectorize it. Probably called by "rice_cray", but there is no explicit information about the vectorization facility in PIPS.

This function is also used to perform loop invariant code motion (Julien Zory).

if s contains a single vertex and if this vertex is not dependent upon itself, we generate a doall loop for it, unless it is a continue statement.

statements that are independent are gathered into the same doall loop

set inner_region = scc_region(s); if (contains_level_l_dependence(s,inner_region,l)) { stat = IsolatedStatement(s, l, task_parallelize_p); debug(9, "CodeGenerate", "isolated comp.that contains dep. at Level %d\n", l); } else { vertex v = VERTEX(CAR(scc_vertices(s))); statement st = vertex_to_statement(v); instruction sbody = statement_instruction(st); nbl = statement_imbrication_level(st); if (instruction_call_p(sbody) && !instruction_continue_p(sbody)) if (nbl>=l-1) stat=IsolatedStatement(s, l, task_parallelize_p); else { loops = load_statement_enclosing_loops(st); lst = gen_nconc(lst, CONS(STATEMENT, st, NIL)); } }

In order to preserve the dependences, statements that have been collected should be generated before the isolated statement that has just been detected

Definition at line 393 of file codegen.c.

397  {
398  list lst = NIL;
399  cons *lsccs;
400  // cons *ps; unused, but still present in commented out code
401  list loops = NIL;
402 
403  cons *block = NIL, *eblock = NIL;
406  int nbl = 0;
407 
408  debug_on("RICE_DEBUG_LEVEL");
409 
410  pips_debug(9, "Begin: starting at level %d ...\n", l);
411  ifdebug(9)
412  print_statement_set(stderr, region);
413 
414  pips_debug(9, "finding and top-sorting sccs ...\n");
416  lsccs = FindAndTopSortSccs(g, region, l);
418 
419  pips_debug(9, "generating code ...\n");
420 
421  FOREACH(scc,s,lsccs) {
422  stata = statement_undefined;
423  if(strongly_connected_p(s, l))
424  stata = ConnectedStatements(g, s, l, task_parallelize_p);
425  else {
426  if(!get_bool_property("PARTIAL_DISTRIBUTION"))
427  /* if s contains a single vertex and if this vertex is not
428  dependent upon itself, we generate a doall loop for it,
429  unless it is a continue statement. */
430  stata = IsolatedStatement(s, l, task_parallelize_p);
431  else {
432  /* statements that are independent are gathered
433  into the same doall loop */
434  stata = IsolatedStatement(s, l, task_parallelize_p);
435 
436  /* set inner_region = scc_region(s);
437  if (contains_level_l_dependence(s,inner_region,l)) {
438  stat = IsolatedStatement(s, l, task_parallelize_p);
439  debug(9, "CodeGenerate",
440  "isolated comp.that contains dep. at Level %d\n",
441  l);
442  }
443  else {
444  vertex v = VERTEX(CAR(scc_vertices(s)));
445  statement st = vertex_to_statement(v);
446  instruction sbody = statement_instruction(st);
447  nbl = statement_imbrication_level(st);
448  if (instruction_call_p(sbody)
449  && !instruction_continue_p(sbody))
450  if (nbl>=l-1)
451  stat=IsolatedStatement(s, l, task_parallelize_p);
452  else {
453  loops = load_statement_enclosing_loops(st);
454  lst = gen_nconc(lst, CONS(STATEMENT, st, NIL));
455  }
456  }
457  */
458  }
459  }
460 
461  /* In order to preserve the dependences, statements that have
462  been collected should be generated before the isolated statement
463  that has just been detected */
464 
465  if(stata != statement_undefined) {
466  ifdebug(9) {
467  pips_debug(9, "generated statement:\n");
469  }
470  (void)MakeNestOfStatementList(l,
471  nbl,
472  &lst,
473  loops,
474  &block,
475  &eblock,
476  task_parallelize_p);
477  INSERT_AT_END(block, eblock, CONS(STATEMENT, stata, NIL));
478  }
479  }
480  gen_free_list(lsccs);
481 
482  (void)MakeNestOfStatementList(l,
483  nbl,
484  &lst,
485  loops,
486  &block,
487  &eblock,
488  task_parallelize_p);
489 
490  switch(gen_length(block)) {
491  case 0:
492  rst = statement_undefined;
493  break;
494  default:
496  }
497 
498  ifdebug(8) {
499  pips_debug(8, "Result:\n");
500 
501  if(rst == statement_undefined)
502  pips_debug(8, "No code to generate\n");
503  else
505 
506  }
507  debug_off();
508  return (rst);
509 }
static list loops
statement make_block_statement(list)
Make a block statement from a list of statement.
Definition: statement.c:616
#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
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#define debug_on(env)
Definition: misc-local.h:157
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define debug_off()
Definition: misc-local.h:160
void print_statement_set(FILE *, set)
statement.c
Definition: statement.c:49
void print_parallel_statement(statement)
Definition: statement.c:156
#define statement_undefined
Definition: ri.h:2419
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
#define INSERT_AT_END(bl, el, c)
a macro to insert an element at the end of a list.
Definition: rice-local.h:34
bool strongly_connected_p(scc s, int l)
this function returns true if scc s is stronly connected at level l, i.e.
Definition: codegen.c:284
statement MakeNestOfStatementList(int l, int nbl, list *lst, list loops, list *block, list *eblock, bool task_parallelize_p)
Definition: codegen.c:350
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.
Definition: codegen.c:571
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...
Definition: codegen.c:614
static bool AK_ignore_this_successor(vertex __attribute__((unused)) v, set region, successor su, int level)
Definition: codegen.c:82
void set_sccs_drivers(bool(*)(set, vertex), bool(*)(vertex, set, successor, int))
scc.c
void reset_sccs_drivers(void)
Definition: scc.c:98
list FindAndTopSortSccs(graph, set, int)
Definition: scc.c:317
#define ifdebug(n)
Definition: sg.c:47

References AK_ignore_this_successor(), AK_ignore_this_vertex(), ConnectedStatements(), CONS, debug_off, debug_on, FindAndTopSortSccs(), FOREACH, gen_free_list(), gen_length(), get_bool_property(), ifdebug, INSERT_AT_END, IsolatedStatement(), loops, make_block_statement(), MakeNestOfStatementList(), NIL, pips_debug, print_parallel_statement(), print_statement_set(), region, reset_sccs_drivers(), set_sccs_drivers(), STATEMENT, statement_undefined, and strongly_connected_p().

Referenced by ConnectedStatements(), distributer(), icm_codegen(), and rice().

+ Here is the call graph for this function:
+ 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 }
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
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
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)
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 }
#define scc_vertices(x)
Definition: dg.h:345
#define vertex_successors(x)
Definition: graph.h:154
#define SUCCESSOR(x)
SUCCESSOR.
Definition: graph.h:86
#define VERTEX(x)
VERTEX.
Definition: graph.h:122
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
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
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:

◆ 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 }
#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)

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:

◆ ignore_this_conflict()

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.

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

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

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

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:

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

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

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:

◆ variable_private_to_loop_p()

static bool variable_private_to_loop_p ( list  loops,
entity  var 
)
static

Check if a variable is private to loop nest.

Parameters
loopsof loop statement

Definition at line 113 of file codegen.c.

114  {
115  FOREACH(STATEMENT, st, loops) {
116  // We filter-out local declarations and loop locals
118  list
119  d =
121 
122  // There is usually no declaration at this level,
123  // but if we find some, warn the user
124  if(statement_declarations(st) != NIL) {
125  pips_user_warning("We don't expect declarations there... (sn : %d)\n",
126  statement_number(st));
128  }
129 
130  ifdebug(8) {
131  print_statement(st);
132  fprintf(stderr, "The list of privatized/private variables : \n");
133  print_entities(l);
134  fprintf(stderr, "\nThe list of locally declared variables : \n");
135  print_entities(d);
136  fprintf(stderr, "\n");
137  }
138 
139  if(gen_find_eq(var, l) != entity_undefined || gen_find_eq(var, d)
140  != entity_undefined) {
141  return true;
142  }
143  }
144  return false;
145 }
void * gen_find_eq(const void *item, const list seq)
Definition: list.c:422
#define pips_user_warning
Definition: misc-local.h:146
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
void print_entities(list l)
Definition: entity.c:167
#define instruction_loop(x)
Definition: ri.h:1520
#define entity_undefined
Definition: ri.h:2761

References entity_undefined, FOREACH, fprintf(), gen_find_eq(), ifdebug, instruction_loop, loop_body, loop_locals, loops, NIL, pips_user_warning, print_entities(), print_statement(), STATEMENT, statement_declarations, statement_instruction, and statement_number.

Referenced by ignore_this_conflict().

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

Variable Documentation

◆ current_module_entity

entity current_module_entity
extern

FI: I did not know this was still used...