PIPS
compile.c
Go to the documentation of this file.
1 /* Copyright 2007-2012 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"
14 
15 #include "prettyprint.h" // for last_statement
16 #include "workspace-util.h" // for compilation_unit_of_module
17 
18 
19 
20 #define STEP_GENERATED_SUFFIX_F ".step_generated.f"
21 #define STEP_GENERATED_SUFFIX_C ".step_generated.c"
22 
23 extern statement compile_mpi(statement stmt, string new_module_name, step_directive drt, int transformation);
24 
25 
26 /*
27  *
28  compile_omp
29  *
30  */
31 
33 {
34  pips_debug(1, "begin\n");
35 
36  string begin_txt, end_txt;
37  bool is_fortran = fortran_module_p(get_current_module_entity());
38  bool is_block_construct = step_directive_to_strings(d, is_fortran, &begin_txt, &end_txt);
39 
40  if(!string_undefined_p(begin_txt))
41  {
42  if(!is_block_construct)
43  {
47  }
48  add_pragma_str_to_statement(stmt, begin_txt, false);
49  }
50 
51  if(!string_undefined_p(end_txt))
52  {
55  add_pragma_str_to_statement(stmt, end_txt, false);
56  }
57 
58  pips_debug(1, "end\n");
59  return stmt;
60 }
61 
63 {
65  pips_debug(1, "begin\n");
66 
68  {
69  statement barrier_stmt = make_empty_block_statement();
72  compile_omp(barrier_stmt, barrier_guard);
73  compile_omp(*block, master_guard);
74  free_step_directive(barrier_guard);
75  free_step_directive(master_guard);
76 
78  }
79 
80  pips_debug(1, "end\n");
81 }
82 
83 
84 /*
85  Suppression du pragma string "STEP" ajoute par step_directive
86 */
88 {
89  list ext_l = NIL;
90 
91  pips_debug(1, "begin\n");
92 
94  {
95  pragma p = extension_pragma(ext);
96  if(pragma_string_p(p) && strncmp(pragma_string(p), STEP_SENTINELLE, strlen(STEP_SENTINELLE))==0)
97  {
98  pips_debug(2,"drop pragma : %s\n", pragma_string(p));
99  free_extension(ext);
100  }
101  else
102  ext_l = CONS(EXTENSION, ext, ext_l);
103  }
106 
107  pips_debug(1, "end\n");
108  return stmt;
109 }
110 
111 /*
112  Compute the new module name
113  Create the new module entity (empty body)
114 
115  No module is created if OpenMP transformation only
116 */
117 
118 
120 {
121 
122  pips_debug(1, "begin\n");
123  bool is_fortran = fortran_module_p(get_current_module_entity());
124 
125  switch(step_directive_type(drt))
126  {
127  case STEP_PARALLEL:
128  *directive_txt = strdup("PAR");
129  break;
130  case STEP_DO:
131  *directive_txt = strdup(is_fortran?"DO":"FOR");
132  break;
133  case STEP_PARALLEL_DO:
134  *directive_txt = strdup(is_fortran?"PARDO":"PARFOR");
135  break;
136  case STEP_MASTER:
137  *directive_txt = strdup("MASTER");
138  break;
139  case STEP_SINGLE:
140  *directive_txt = strdup("SINGLE");
141  break;
142  case STEP_BARRIER:
143  *directive_txt = strdup("BARRIER");
144  break;
145  default: assert(0);
146  }
147 
148  pips_debug(1, "end *directive_txt = %s\n", *directive_txt);
149 }
150 
152 {
153  int transformation_type = -1;
154  pips_debug(2, "begin\n");
155 
157  {
158  /* que se passe t-il si plusieurs clauses de transformation ?*/
159 
161  transformation_type = step_clause_transformation(c);
162  }
163 
164  pips_debug(2,"end transformation_type : %d\n", transformation_type);
165 
166  return transformation_type;
167 }
168 
169 static int get_directive_transformation(step_directive drt, string *transformation_txt)
170 {
171  int transformation = -1;
172  pips_debug(1, "begin\n");
173 
175 
176  switch (transformation)
177  {
179  *transformation_txt = strdup("MPI");
180  break;
182  *transformation_txt = strdup("HYBRID");
183  break;
186  *transformation_txt = strdup("");
187  break;
188  default:
189  assert(0);
190  }
191 
192  pips_debug(1, "end transformation = %d\n", transformation);
193  return transformation;
194 }
195 
196 static entity create_new_module_entity (list *last_module_name, string directive_txt, string transformation_txt)
197 {
198  string previous_name, new_module_name;
199  string prefix;
200  entity new_module;
201 
202  previous_name = STRING(CAR(*last_module_name));
203 
204  assert(asprintf(&prefix,"%s_%s_%s", previous_name, directive_txt, transformation_txt)>=0);
205  new_module_name = build_new_top_level_module_name(prefix, true);
207 
208  free(prefix);
209 
210  *last_module_name = CONS(STRING, new_module_name, *last_module_name);
211  pips_debug(1, "new_module %p : %s\n", new_module, new_module_name);
212  return new_module;
213 }
214 
215 static bool compile_filter(statement stmt, list *last_module_name)
216 {
217  string directive_txt = NULL, transformation_txt = NULL;
218  step_directive drt;
219  int transformation_type;
220 
222  return true;
223 
224  pips_debug(1, "begin\n");
225 
226  drt = step_directives_load(stmt);
228  transformation_type = get_directive_transformation(drt, &transformation_txt);
229 
230  if (transformation_type == STEP_TRANSFORMATION_MPI || transformation_type == STEP_TRANSFORMATION_HYBRID)
231  {
232  entity new_module = create_new_module_entity(last_module_name, directive_txt, transformation_txt);
233  pips_debug(1, "New entity module created : %s\n", entity_name(new_module));
234  }
235 
236 
238  free(transformation_txt);
239 
240  pips_debug(1, "end\n");
241  return true;
242 }
243 
244 
245 static void compile_rewrite(statement stmt, list *last_module_name)
246 {
247 
248  int transformation;
249  string new_module_name;
250  step_directive drt;
251 
252  pips_debug(1, "begin\n");
253 
255  return;
256 
257  new_module_name = STRING(CAR(*last_module_name));
258  pips_debug(1, "stack_name current name = %s\n", new_module_name);
259 
260  drt = step_directives_load(stmt);
261  ifdebug(3)
263 
265 
267 
268  switch( transformation )
269  {
271  break;
273  compile_omp(stmt, drt);
274  break;
277  compile_mpi(stmt, new_module_name, drt, transformation);
278  POP(*last_module_name);
279  break;
280  default:
281  assert(0);
282  }
283 
284  pips_debug(1, "end\n");
285 }
286 
287 
288 void step_compile_analysed_module(const char* module_name, string finit_name)
289 {
290  pips_debug(1, "begin\n");
291 
294 
297 
299  load_step_comm();
300 
301  statement_effects rw_effects = (statement_effects)db_get_memory_resource(DBR_REGIONS, module_name, false);
302  statement_effects cummulated_rw_effects = (statement_effects)db_get_memory_resource(DBR_CUMULATED_EFFECTS, module_name, false);
303  set_rw_effects(rw_effects);
304  set_cumulated_rw_effects(cummulated_rw_effects);
305 
306  /* Code transformation */
307  list last_module_name = CONS(STRING, (string)module_name, NIL);
308 
310 
312  {
313  string init_subroutine_name;
314  init_subroutine_name = fortran_module_p(get_current_module_entity())?
317  statement init_stmt = call_STEP_subroutine2(init_subroutine_name, NULL);
318  statement finalize_stmt = call_STEP_subroutine2(RT_STEP_finalize, NULL);
319 
321  insert_statement(last_statement(stmt), finalize_stmt, true);
322  }
323 
326  free_statement_effects(cummulated_rw_effects);
327  free_statement_effects(rw_effects);
328 
329  reset_step_comm();
333 
334  /* File generation */
335  text code_txt = text_named_module(module, module, stmt);
336  bool saved_b1 = get_bool_property("PRETTYPRINT_ALL_DECLARATIONS");
337  bool saved_b2 = get_bool_property("PRETTYPRINT_STATEMENT_NUMBER");
338  set_bool_property("PRETTYPRINT_ALL_DECLARATIONS", true);
339  set_bool_property("PRETTYPRINT_STATEMENT_NUMBER", false);
340 
341  FILE *f = safe_fopen(finit_name, "w");
342  print_text(f, code_txt);
343  safe_fclose(f, finit_name);
344 
345  set_bool_property("PRETTYPRINT_ALL_DECLARATIONS", saved_b1);
346  set_bool_property("PRETTYPRINT_STATEMENT_NUMBER", saved_b2);
347  free_text(code_txt);
349  pips_debug(1, "end\n");
350 }
351 
352 
353 /* generated source: no analyse and no compilation necessary. Keep the source as it is. */
354 void step_compile_generated_module(const char* module_name, string finit_name)
355 {
356  pips_debug(1, "begin\n");
357 
358  string source_file, fsource_file;
360  bool is_fortran = fortran_module_p(module);
361 
362  source_file = db_get_memory_resource(is_fortran?DBR_INITIAL_FILE:DBR_C_SOURCE_FILE, module_name, true);
363 
364  assert(asprintf(&fsource_file,"%s/%s" , db_get_current_workspace_directory(), source_file)>=0);
365  pips_debug(1, "Copie from: %s\n", fsource_file);
366  safe_copy(fsource_file, finit_name);
367 
369  {
370  safe_system(concatenate("echo '#include \"step_api.h\"' >>",finit_name, NULL));
371  pips_debug(1, "\tAdd prototype for STEP generated modules\n");
373  int n = gen_array_nitems(modules), i;
374  FILE *out = safe_fopen(finit_name, "a");
375  for (i=0; i<n; i++)
376  {
377  string name = gen_array_item(modules, i);
378  if (same_string_p((const char*)module_name, (const char*)compilation_unit_of_module(name)) &&
379  !same_string_p(module_name, name) &&
380  !step_analysed_module_p(name))
381  {
386  }
387  }
388  safe_fclose(out, finit_name);
389  }
390  pips_debug(1, "end\n");
391 }
392 
393 bool step_compile(const char* module_name)
394 {
395  debug_on("STEP_COMPILE_DEBUG_LEVEL");
396  pips_debug(1, "Begin considering module_name = %s\n", module_name);
397 
399 
400  bool is_fortran = fortran_module_p(module);
401  string init_name, finit_name;
402 
404  assert(asprintf(&finit_name,"%s/%s" , db_get_current_workspace_directory(), init_name)>=0);
405 
407  {
408  /* analysed source : let's do the transformations */
410  }
411  else
412  {
413  /* generated module: nothing to do but copy the generated source */
415  }
416 
417  DB_PUT_FILE_RESOURCE(DBR_STEP_FILE, module_name, finit_name);
418 
419  pips_debug(1, "End\n");
420  debug_off();
421  return true;
422 }
void free_statement_effects(statement_effects p)
Definition: effects.c:971
void free_extension(extension p)
Definition: ri.c:895
language copy_language(language p)
LANGUAGE.
Definition: ri.c:1202
void free_statement(statement p)
Definition: ri.c:2189
void free_step_directive(step_directive p)
Definition: step_private.c:372
step_directive make_step_directive(intptr_t a1, statement a2, list a3)
Definition: step_private.c:405
void free_text(text p)
Definition: text.c:74
gen_array_t db_get_module_list_initial_order(void)
Definition: database.c:1151
#define RT_STEP_init_fortran_order
Definition: STEP_name.h:71
#define RT_STEP_init_c_order
Definition: STEP_name.h:70
#define RT_STEP_finalize
Definition: STEP_name.h:64
static FILE * out
Definition: alias_check.c:128
bool step_analysed_module_p(const char *module_name)
Definition: analyse.c:179
void reset_step_comm()
Definition: analyse.c:199
void load_step_comm()
Definition: analyse.c:190
size_t gen_array_nitems(const gen_array_t a)
Definition: array.c:131
void * gen_array_item(const gen_array_t a, size_t i)
Definition: array.c:143
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
static char * directive_txt
statement call_STEP_subroutine2(string name,...)
Definition: compile_RT.c:819
string compilation_unit_of_module(const char *)
The output is undefined if the module is referenced but not defined in the workspace,...
Definition: module.c:350
void set_rw_effects(statement_effects)
void set_cumulated_rw_effects(statement_effects)
void reset_cumulated_rw_effects(void)
void reset_rw_effects(void)
struct _newgen_struct_statement_effects_ * statement_effects
Definition: effects.h:210
bool compilation_unit_p(const char *module_name)
The names of PIPS entities carry information about their nature.
Definition: entity_names.c:56
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
void safe_copy(char *source, char *target)
Definition: file.c:706
FILE * safe_fopen(const char *filename, const char *what)
Definition: file.c:67
int safe_fclose(FILE *stream, const char *filename)
Definition: file.c:77
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
Definition: genC.h:285
#define STRING(x)
Definition: genC.h:87
void free(void *)
statement make_block_statement(list)
Make a block statement from a list of statement.
Definition: statement.c:616
statement make_empty_block_statement(void)
Build an empty statement (block/sequence)
Definition: statement.c:625
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
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#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
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#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
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_FILE_RESOURCE
Put a file resource into the current workspace database.
Definition: pipsdbm-local.h:85
list statement_block(statement)
Get the list of block statements of a statement sequence.
Definition: statement.c:1338
bool empty_statement_or_continue_p(statement)
Return true if the statement is an empty instruction block or a continue or a recursive combination o...
Definition: statement.c:474
void insert_statement(statement, statement, bool)
This is the normal entry point.
Definition: statement.c:2570
statement make_plain_continue_statement(void)
Make a simple continue statement to be used as a NOP or ";" in C.
Definition: statement.c:964
string db_build_file_resource_name(const char *rname, const char *oname, const char *suffix)
returns an allocated file name for a file resource.
Definition: lowlevel.c:169
#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 asprintf
Definition: misc-local.h:225
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define debug_off()
Definition: misc-local.h:160
void safe_system(string)
system.c
Definition: system.c:38
static statement init_stmt
#define assert(ex)
Definition: newgen_assert.h:41
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define same_string_p(s1, s2)
#define string_undefined_p(s)
Definition: newgen_types.h:41
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
static char * module
Definition: pips.c:74
string db_get_current_workspace_directory(void)
Definition: workspace.c:96
text text_named_module(entity, entity, statement)
void fprint_statement(FILE *, statement)
Print statement "s" on file descriptor "fd".
Definition: statement.c:68
statement last_statement(statement)
A simplified version of find_last_statement() located in prettyprint.c and designed to be used within...
Definition: statement.c:168
void set_bool_property(const char *, bool)
static const char * prefix
#define statement_block_p(stat)
#define module_language(e)
implemented as a macro to allow lhs
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
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
entity make_empty_subroutine(const char *name, language l)
Definition: entity.c:268
bool entity_main_module_p(entity e)
Definition: entity.c:700
bool fortran_module_p(entity m)
Test if a module is in Fortran.
Definition: entity.c:2799
string build_new_top_level_module_name(const char *prefix, bool prevent_suffix)
Get a new name for a module built from a prefix.
Definition: module.c:55
void add_pragma_str_to_statement(statement st, const char *s, bool copy_flag)
Add a string as a pragma to a statement.
Definition: pragma.c:425
#define pragma_string(x)
Definition: ri.h:2033
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define pragma_string_p(x)
Definition: ri.h:2031
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define extension_pragma(x)
Definition: ri.h:1295
#define EXTENSION(x)
EXTENSION.
Definition: ri.h:1253
#define entity_name(x)
Definition: ri.h:2790
#define statement_extensions(x)
Definition: ri.h:2464
#define statement_declarations(x)
Definition: ri.h:2460
#define extensions_extension(x)
Definition: ri.h:1330
#define statement_undefined_p(x)
Definition: ri.h:2420
#define statement_undefined
Definition: ri.h:2419
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
struct _newgen_struct_transformation_ * transformation
Definition: sac_private.h:138
char * strdup()
#define ifdebug(n)
Definition: sg.c:47
statement compile_omp(statement stmt, step_directive d)
compile.c
Definition: compile.c:32
statement compile_mpi(statement stmt, string new_module_name, step_directive drt, int transformation)
Definition: compile_mpi.c:517
void step_compile_generated_module(const char *module_name, string finit_name)
generated source: no analyse and no compilation necessary.
Definition: compile.c:354
#define STEP_GENERATED_SUFFIX_F
Copyright 2007-2012 Alain Muller, Frederique Silber-Chaussumier.
Definition: compile.c:20
#define STEP_GENERATED_SUFFIX_C
Definition: compile.c:21
static int get_directive_transformation_type(step_directive drt)
Definition: compile.c:151
static entity create_new_module_entity(list *last_module_name, string directive_txt, string transformation_txt)
Definition: compile.c:196
static int get_directive_transformation(step_directive drt, string *transformation_txt)
Definition: compile.c:169
void step_compile_analysed_module(const char *module_name, string finit_name)
Definition: compile.c:288
void add_omp_guard(statement *block)
Definition: compile.c:62
static bool compile_filter(statement stmt, list *last_module_name)
Definition: compile.c:215
static void get_module_name_directive_suffix(step_directive drt, string *directive_txt)
Definition: compile.c:119
static statement remove_STEP_pragma(statement stmt)
Definition: compile.c:87
bool step_compile(const char *module_name)
Definition: compile.c:393
static void compile_rewrite(statement stmt, list *last_module_name)
Definition: compile.c:245
#define STEP_TRANSFORMATION_HYBRID
Definition: defines-local.h:57
#define STEP_TRANSFORMATION_SEQ
Definition: defines-local.h:58
#define STEP_TRANSFORMATION_OMP
Definition: defines-local.h:55
#define STEP_TRANSFORMATION_MPI
Definition: defines-local.h:56
#define STEP_SENTINELLE
STEP sentinelle.
Definition: defines-local.h:48
bool step_directives_bound_p(statement stmt)
Definition: directives.c:121
bool step_directive_to_strings(step_directive d, bool is_fortran, string *begin_txt, string *end_txt)
Definition: directives.c:147
void step_directives_reset()
Definition: directives.c:103
void step_directive_print(step_directive d)
Definition: directives.c:362
step_directive step_directives_load(statement stmt)
Definition: directives.c:116
void step_directives_init(bool first_p)
Definition: directives.c:88
#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_transformation_p(x)
Definition: step_private.h:297
#define step_directive_type(x)
Definition: step_private.h:429
#define step_directive_clauses(x)
Definition: step_private.h:433
#define step_clause_transformation(x)
Definition: step_private.h:299
#define STEP_CLAUSE(x)
STEP_CLAUSE.
Definition: step_private.h:227
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
Definition: statement.c:54
void print_text(FILE *fd, text t)
Definition: print.c:195