PIPS
directives.c
Go to the documentation of this file.
1 /* Copyright 2007, 2008, 2009 Alain Muller, Frederique Silber-Chaussumier
2 
3 This file is part of STEP.
4 
5 The program is distributed under the terms of the GNU General Public
6 License.
7 */
8 
9 #ifdef HAVE_CONFIG_H
10  #include "pips_config.h"
11 #endif
12 
13 #include "defines-local.h" // for STEP_DEBUG_STATEMENT
14 #include "prettyprint.h"
15 
17 
19 {
20  pips_debug(2, "begin\n");
21 
22  switch(step_directive_type(drt))
23  {
24  case STEP_PARALLEL:
26  break;
27  case STEP_DO:
29  break;
30  case STEP_PARALLEL_DO:
32  break;
33  case STEP_MASTER:
35  break;
36  case STEP_SINGLE:
38  break;
39  case STEP_BARRIER:
41  break;
42  case STEP_THREADPRIVATE:
44  break;
45  default: assert(0);
46  }
47 
48  pips_debug(2, "end\n");
49 }
50 
52 {
53  switch(step_directive_type(drt))
54  {
55  case STEP_PARALLEL:
56  pips_debug(1, "step_directive_type = STEP_PARALLEL\n");
57  break;
58  case STEP_PARALLEL_DO:
59  pips_debug(1, "step_directive_type = STEP_PARALLEL_DO\n");
60  break;
61  case STEP_DO:
62  pips_debug(1, "step_directive_type = STEP_DO\n");
63  break;
64  case STEP_MASTER:
65  pips_debug(1, "step_directive_type = STEP_MASTER\n");
66  break;
67  case STEP_BARRIER:
68  pips_debug(1, "step_directive_type = STEP_BARRIER\n");
69  break;
70  case STEP_THREADPRIVATE:
71  pips_debug(1, "step_directive_type = STEP_THREADPRIVATE\n");
72  break;
73  default:
74  pips_debug(1, "step_directive_type = UNKNOWN\n");
75  break;
76  }
77 }
78 
80 {
81  STEP_DIRECTIVES_MAP(block_stmt, d,
82  {
83  assert(!statement_undefined_p(block_stmt));
85  }, get_directives());
86 }
87 
88 void step_directives_init(bool first_p)
89 {
90  pips_debug(4, "begin first_p = %d\n", first_p);
91 
92  if (first_p)
93  init_directives();
94  else
95  {
97  set_directives((step_directives)db_get_memory_resource(DBR_STEP_DIRECTIVES, module_name, true));
98  }
99 
100  pips_debug(4, "end\n");
101 }
102 
104 {
105  reset_directives();
106 }
107 
109 {
111  DB_PUT_MEMORY_RESOURCE(DBR_STEP_DIRECTIVES, module_name, get_directives());
112  reset_directives();
113 }
114 
115 
117 {
118  return load_directives(stmt);
119 }
120 
122 {
123  return bound_directives_p(stmt);
124 }
125 
127 {
129  store_directives(stmt, d);
130 }
131 
132 #define SB_LIST_VARIABLE(sb, list_var, txt_begin) \
133  if(!set_empty_p(list_var)) \
134  { \
135  string s = string_undefined; \
136  FOREACH(ENTITY, variable, set_to_sorted_list(list_var, (gen_cmp_func_t)compare_entities)) \
137  { \
138  if(s == string_undefined) \
139  s=strdup(concatenate(txt_begin, entity_user_name(variable), NULL)); \
140  else \
141  s=strdup(concatenate(", ", entity_user_name(variable), NULL)); \
142  string_buffer_append(sb, s); \
143  } \
144  string_buffer_append(sb, strdup(")")); \
145  }
146 
147 bool step_directive_to_strings(step_directive d, bool is_fortran, string *begin_txt, string *end_txt)
148 {
149  bool block_directive = true;
150  bool end_directive = is_fortran;
151 
153  switch(step_directive_type(d))
154  {
155  case STEP_PARALLEL:
156  directive_txt = strdup("parallel");
157  break;
158  case STEP_DO:
159  directive_txt = strdup(is_fortran?"do":"for");
160  block_directive = is_fortran;
161  break;
162  case STEP_PARALLEL_DO:
163  directive_txt = strdup(is_fortran?"parallel do":"parallel for");
164  block_directive = is_fortran;
165  break;
166  case STEP_MASTER:
167  directive_txt = strdup("master");
168  break;
169  case STEP_SINGLE:
170  directive_txt = strdup("single");
171  break;
172  case STEP_BARRIER:
173  directive_txt = strdup("barrier");
174  block_directive = false;
175  end_directive = false;
176  break;
177  case STEP_THREADPRIVATE:
178  directive_txt = strdup("threadprivate");
179  block_directive = false;
180  end_directive = false;
181  break;
182  default:
183  pips_internal_error("unpexpected step directive type");
184  }
185 
186  /* clause */
187  set copyin_l = set_make(set_pointer);
188  set private_l = set_make(set_pointer);
189  set shared_l = set_make(set_pointer);
190  set threadprivate_l = set_make(set_pointer);
191  set firstprivate_l = set_make(set_pointer);
192  list schedule_l = list_undefined;
193  bool nowait = false;
194 
195  int op;
196  set reductions_l[STEP_UNDEF_REDUCE];
197  for(op=0; op<STEP_UNDEF_REDUCE; op++)
198  reductions_l[op] = set_make(set_pointer);
199 
201  {
202  switch (step_clause_tag(c))
203  {
205  set_append_list(copyin_l, step_clause_copyin(c));
206  break;
208  set_append_list(private_l, step_clause_private(c));
209  break;
211  set_append_list(shared_l, step_clause_shared(c));
212  break;
214  set_append_list(threadprivate_l, step_clause_threadprivate(c));
215  break;
217  set_append_list(firstprivate_l, step_clause_firstprivate(c));
218  break;
220  nowait = true;
221  break;
224  set_add_element(reductions_l[op], reductions_l[op], variable);
225  }, step_clause_reduction(c));
226  break;
228  schedule_l = step_clause_schedule(c);
229  break;
231  /* transformation clause is not printed */
232  break;
233  default: assert(0);
234  }
235  }
236 
237 
238  if(end_directive)
239  *end_txt = strdup(concatenate("omp end ",directive_txt, nowait?" nowait":"", NULL));
240  else
241  *end_txt = string_undefined;
242 
244  string_buffer_cat(sb, strdup("omp "), strdup(directive_txt), NULL);
245 
246  SB_LIST_VARIABLE(sb, copyin_l, " copyin(");
247  SB_LIST_VARIABLE(sb, private_l, " private(");
248  SB_LIST_VARIABLE(sb, shared_l, " shared(");
249  SB_LIST_VARIABLE(sb, threadprivate_l, "(");
250  SB_LIST_VARIABLE(sb, firstprivate_l, " firstprivate(");
251 
252  if(!list_undefined_p(schedule_l))
253  {
254  string s = string_undefined;
255  FOREACH(STRING, str, schedule_l)
256  {
257  if(s == string_undefined)
258  s=strdup(concatenate(" schedule(", str, NULL));
259  else
260  s=strdup(concatenate(", ", str, NULL));
262  }
264  }
265 
266  string op_txt[STEP_UNDEF_REDUCE]={" reduction(*: "," reduction(max: "," reduction(min: "," reduction(+: "};
267  for(op=0; op<STEP_UNDEF_REDUCE; op++)
268  SB_LIST_VARIABLE(sb, reductions_l[op], op_txt[op]);
269 
270  if(nowait && !end_directive)
271  string_buffer_append(sb, strdup(" nowait"));
272 
273  *begin_txt = string_buffer_to_string(sb);
275 
276  ifdebug(4)
277  {
278  printf("ÞÞÞÞÞÞÞÞÞ directive begin : %s\n", *begin_txt);
279  printf("ÞÞÞÞÞÞÞÞÞ directive end : %s\n", end_directive?*end_txt:"");
280  }
281 
282  return block_directive;
283 }
284 
285 
287 {
289  pips_debug(3, "begin\n");
290 
291  switch(step_directive_type(d))
292  {
293  case STEP_DO:
294  case STEP_PARALLEL_DO:
295  {
296  // on retourne le corps de boucle
298  pips_assert("1 statement", gen_length(block) == 1);
299 
300  stmt = STATEMENT(CAR(block));
301 
304  else if (statement_forloop_p(stmt))
306  else
307  pips_assert("not a loop", false);
308  break;
309  }
310  default:
311  {
312  // on retourne le block de la directive
313  }
314  }
315 
316  pips_debug(3, "end\n");
317  return stmt;
318 }
319 
321 {
322  list index_l = NIL;
324 
325  pips_debug(4, "begin\n");
326  switch(step_directive_type(d))
327  {
328  case STEP_DO:
329  case STEP_PARALLEL_DO:
330  {
332  pips_assert("1 statement", gen_length(block) == 1);
333 
334  stmt = STATEMENT(CAR(block));
335 
337  index_l = CONS(ENTITY, loop_index(statement_loop(stmt)), index_l);
338  else if (statement_forloop_p(stmt))
339  {
341  pips_assert("an assignment", assignment_expression_p(init));
343  expression lhs = EXPRESSION(CAR(assign_params));
344  entity e = expression_to_entity(lhs);
345  pips_assert("an entity", !entity_undefined_p(e));
346  index_l = CONS(ENTITY, e, index_l);
347  }
348  else
349  pips_assert("not a loop", false);
350  break;
351  }
352  default:
353  {
354  // on retourne la liste vide
355  }
356  }
357 
358  pips_debug(4, "end\n");
359  return gen_nreverse(index_l);
360 }
361 
363 {
364  int type = step_directive_type(d);
365  list clauses = step_directive_clauses(d);
366  string begin_txt, end_txt;
367  bool is_fortran = fortran_module_p(get_current_module_entity());
368  bool is_block_construct = step_directive_to_strings(d, is_fortran, &begin_txt, &end_txt);
369 
370  pips_debug(1, "begin ====> TYPE %d : \nNB clauses : %d\n\tdirective begin : %s\n",
371  type, (int)gen_length(clauses), begin_txt);
372  if (is_block_construct && !empty_comments_p(end_txt)) pips_debug(1,"\tdirective end : %s\n", end_txt);
373 
374  ifdebug(1)
375  {
378  pips_debug(1, "----> on statement :\n");
380  pips_debug(1, "\n");
381  }
382  /*
383  ifdebug(2)
384  {
385  statement stmt = step_directive_basic_workchunk(d);
386  assert(!statement_undefined_p(stmt));
387 
388  string index_str=strdup("");
389  FOREACH(ENTITY, e , step_directive_basic_workchunk_index(d))
390  {
391  string previous = index_str;
392  index_str = strdup(concatenate(previous, entity_local_name(e), " ", NULL));
393  free(previous);
394  }
395  pips_debug(2, "\n----> basic workchunk (index : [%s] )\n", index_str);
396  print_statement(stmt);
397  pips_debug(2, "\n");
398  }
399  */
400  pips_debug(1, "end\n");
401 }
402 
403 
405 {
406  pips_debug(4, "begin\n");
407  list private_l = NIL;
408  list clauses = step_directive_clauses(directive);
409  FOREACH(STEP_CLAUSE,c,clauses)
410  {
411  switch (step_clause_tag(c))
412  {
414  private_l = gen_append(step_clause_private(c), private_l);
415  break;
416  default:
417  break;
418  }
419  }
420  pips_debug(4, "end\n");
421  return private_l;
422 }
423 
425 {
426  pips_debug(4, "begin\n");
428  list private_l;
430  pips_debug(4, "end\n");
431  return gen_in_list_p(e, private_l);
432 }
#define STEP_MASTER_NAME
Definition: STEP_name.h:33
#define STEP_PARALLEL_DO_NAME
Definition: STEP_name.h:39
#define STEP_DO_NAME
Definition: STEP_name.h:23
#define STEP_SINGLE_NAME
Definition: STEP_name.h:46
#define STEP_PARALLEL_NAME
Definition: STEP_name.h:40
static void end_directive(void)
static char * directive_txt
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
#define STRING(x)
Definition: genC.h:87
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
#define list_undefined_p(c)
Return if a list is undefined.
Definition: newgen_list.h:75
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
#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
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
bool gen_in_list_p(const void *vo, const list lx)
tell whether vo belongs to lx
Definition: list.c:734
#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
list gen_append(list l1, const list l2)
Definition: list.c:471
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
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
list statement_block(statement)
Get the list of block statements of a statement sequence.
Definition: statement.c:1338
loop statement_loop(statement)
Get the loop of a statement.
Definition: statement.c:1374
forloop statement_forloop(statement)
Get the forloop of a statement.
Definition: statement.c:1426
bool statement_forloop_p(statement)
Definition: statement.c:374
bool statement_loop_p(statement)
Definition: statement.c:349
bool empty_comments_p(const char *)
Definition: statement.c:107
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_internal_error
Definition: misc-local.h:149
#define assert(ex)
Definition: newgen_assert.h:41
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
@ set_pointer
Definition: newgen_set.h:44
set set_append_list(set, const list)
add list l items to set s, which is returned.
Definition: set.c:460
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
void string_buffer_free_all(string_buffer *)
free string buffer structure and force string freeing
Definition: string_buffer.c:94
void string_buffer_append(string_buffer, const string)
append string s (if non empty) to string buffer sb, the duplication is done if needed according to th...
string string_buffer_to_string(const string_buffer)
return malloc'ed string from string buffer sb
string_buffer string_buffer_make(bool dup)
allocate a new string buffer
Definition: string_buffer.c:58
void string_buffer_cat(string_buffer, const string,...)
append a NULL terminated list of string to sb.
#define string_undefined
Definition: newgen_types.h:40
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
#define statement_block_p(stat)
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
static int init
Maximal value set for Fortran 77.
Definition: entity.c:320
bool fortran_module_p(entity m)
Test if a module is in Fortran.
Definition: entity.c:2799
bool assignment_expression_p(expression e)
Test if an expression is an assignment operation.
Definition: expression.c:979
entity expression_to_entity(expression e)
just returns the entity of an expression, or entity_undefined
Definition: expression.c:3140
#define loop_body(x)
Definition: ri.h:1644
#define forloop_initialization(x)
Definition: ri.h:1366
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define entity_undefined_p(x)
Definition: ri.h:2762
#define syntax_call(x)
Definition: ri.h:2736
#define call_arguments(x)
Definition: ri.h:711
#define statement_undefined_p(x)
Definition: ri.h:2420
#define expression_syntax(x)
Definition: ri.h:1247
#define forloop_body(x)
Definition: ri.h:1372
#define loop_index(x)
Definition: ri.h:1640
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
char * strdup()
int printf()
#define ifdebug(n)
Definition: sg.c:47
void step_directives_save()
Definition: directives.c:108
bool step_directives_bound_p(statement stmt)
Definition: directives.c:121
GENERIC_LOCAL_FUNCTION(directives, step_directives)
Copyright 2007, 2008, 2009 Alain Muller, Frederique Silber-Chaussumier.
void get_step_directive_name(step_directive drt, string *directive_txt)
Warning! Do not modify this file that is automatically generated!
Definition: directives.c:18
void step_directives_store(statement stmt, step_directive d)
Definition: directives.c:126
void step_directives_print()
Definition: directives.c:79
bool step_private_p(statement stmt, entity e)
Definition: directives.c:424
bool step_directive_to_strings(step_directive d, bool is_fortran, string *begin_txt, string *end_txt)
Definition: directives.c:147
void step_directive_type_print(step_directive drt)
Definition: directives.c:51
void step_directives_reset()
Definition: directives.c:103
void step_directive_print(step_directive d)
Definition: directives.c:362
#define SB_LIST_VARIABLE(sb, list_var, txt_begin)
Definition: directives.c:132
static list step_directive_omp_get_private_entities(step_directive directive)
Definition: directives.c:404
step_directive step_directives_load(statement stmt)
Definition: directives.c:116
void step_directives_init(bool first_p)
Definition: directives.c:88
list step_directive_basic_workchunk_index(step_directive d)
Definition: directives.c:320
statement step_directive_basic_workchunk(step_directive d)
Definition: directives.c:286
#define STEP_THREADPRIVATE
Definition: step_common.h:50
#define STEP_UNDEF_REDUCE
Definition: step_common.h:95
#define STEP_SINGLE
Definition: step_common.h:49
#define STEP_PARALLEL
Handled construction.
Definition: step_common.h:43
#define STEP_PARALLEL_DO
Definition: step_common.h:45
#define STEP_MASTER
Definition: step_common.h:46
#define STEP_DO
Definition: step_common.h:44
#define STEP_BARRIER
Definition: step_common.h:48
#define step_clause_copyin(x)
Definition: step_private.h:308
#define step_directive_type(x)
Definition: step_private.h:429
@ is_step_clause_reduction
Definition: step_private.h:248
@ is_step_clause_private
Definition: step_private.h:249
@ is_step_clause_transformation
Definition: step_private.h:251
@ is_step_clause_nowait
Definition: step_private.h:252
@ is_step_clause_copyin
Definition: step_private.h:254
@ is_step_clause_threadprivate
Definition: step_private.h:253
@ is_step_clause_schedule
Definition: step_private.h:256
@ is_step_clause_firstprivate
Definition: step_private.h:255
@ is_step_clause_shared
Definition: step_private.h:250
#define step_clause_private(x)
Definition: step_private.h:293
#define step_directive_block(x)
Definition: step_private.h:431
#define step_clause_firstprivate(x)
Definition: step_private.h:311
#define step_directive_clauses(x)
Definition: step_private.h:433
#define STEP_DIRECTIVES_MAP(k, v, c, f)
Definition: step_private.h:388
#define step_clause_tag(x)
Definition: step_private.h:287
#define step_clause_schedule(x)
Definition: step_private.h:314
#define step_clause_shared(x)
Definition: step_private.h:296
#define step_clause_threadprivate(x)
Definition: step_private.h:305
#define STEP_CLAUSE(x)
STEP_CLAUSE.
Definition: step_private.h:227
#define step_clause_reduction(x)
Definition: step_private.h:290
#define MAP_ENTITY_INT_MAP(k, v, c, f)
Definition: step_private.h:217
internally defined structure.
Definition: string_buffer.c:47
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
Definition: statement.c:4047
Definition: statement.c:54