PIPS
pragma.c
Go to the documentation of this file.
1 /**
2  * @file pragma.c
3  * @brief This file holds the generation of omp pragma for reductions.
4  * @author pierre villalon <pierre.villalon@hpc-project.com>
5  * @date 2009-05-24
6  */
7 #ifdef HAVE_CONFIG_H
8  #include "pips_config.h"
9 #endif
10 
11 #include "local-header.h"
12 #include "prettyprint.h"
13 
14 //***********************************************************Local constant
15 static const string OMP_PRAGMA_FOR_HEADER_C = "omp parallel for";
16 static const string OMP_PRAGMA_FOR_HEADER_F = "omp parallel do";
17 static const string REDUCTION_KEYWORD = "reduction";
18 
19 //***********************************************************Local variable
20 static bool all_reduction = false;
21 
22 
23 //***********************************************************Local functions
24 
25 ///@brief reset the all_reduction flag
26 static void reset_all_reduction (void) {
27  all_reduction = true;
28 }
29 
30 ///@return true if the statement is a reduction
31 ///@param stmt, the statement to test for reduction
33  // test that we have a reachable statement
34  if (bound_printed_reductions_p (stmt) == false) return false;
36  return (size != 0);
37 }
38 
39 ///@brief remenber if all the statement analazed are reduction
40 ///since the last reset
41 ///@return void
42 ///@param stmt, the statement to test for reduction
45 }
46 
47 ///@return true if the reductions are applied on scalars only
48 ///@param reds, the reductions to analyze
49 static bool reductions_on_scalar (reductions reds) {
50  FOREACH (REDUCTION, red, reductions_list(reds)) {
52  if (reference_indices (ref) != NIL) return false;
53  }
54  return true;
55 }
56 
57 //******************************************************PRAGMA AS EXPRESSIONS
58 
59 ///@return an entiy describing the reduction operator
60 ///@param o the reduction operator to analyze
62 
63  entity result = entity_undefined;
65 
66  switch(t) {
68  pips_internal_error("unexpected none reduction operator tag!");
69  break;
72  break;
75  break;
78  break;
81  break;
84  break;
86  result = (prettyprint_language_is_fortran_p () == true ?
89  break;
91  result = (prettyprint_language_is_fortran_p () == true ?
94  break;
97  break;
100  break;
103  break;
105  pips_assert ("not a C reduction operator", prettyprint_language_is_fortran_p () == true);
107  break;
109  pips_assert ("not a C reduction operator", prettyprint_language_is_fortran_p () == true);
111  break;
112  default:
113  pips_internal_error("unexpected reduction operator tag!");
114  break;
115  }
116  return result;
117 }
118 
119 ///@return a list of expression for reduction r
120 ///@param r the reduction to process
122 {
123  // prepare the expressions list that specifies the variable
124  // and the operator
128  list args = NIL;
129  args = gen_expression_cons (expr, args);
130  // and now the operator
135  args = gen_expression_cons (expr, args);
136 
137  // first prepare "reduction" as an expression
139  call c = make_call (e, args);
140  s = make_syntax_call (c);
142 
143  pips_debug(5, "finish\n");
144  return result;
145 }
146 
147 //***********************************************************PRAGMA AS STRING
148 
149 ///@return a (static) string describing the reduction operator for open mp
150 ///@param o the reduction operator to analyze
152 
154  string result = string_undefined;
155 
156  switch(t) {
158  result = "none";
159  break;
161  result = "+";
162  break;
164  result = "+";
165  break;
167  result = "*";
168  break;
170  result = "MIN";
171  break;
173  result = "MAX";
174  break;
176  result = (prettyprint_language_is_fortran_p () == true) ? ".AND." : "&&";
177  break;
179  result = (prettyprint_language_is_fortran_p () == true) ? ".OR." :"||";
180  break;
182  result = "|";
183  break;
185  result = "^";
186  break;
188  result = "&";
189  break;
191  pips_assert ("not a C reduction operator", prettyprint_language_is_fortran_p () == true);
192  result = ".EQV.";
193  break;
195  pips_assert ("not a C reduction operator", prettyprint_language_is_fortran_p () == true);
196  result = ".NEQV.";
197  break;
198  default:
199  pips_internal_error("unexpected reduction operator tag!");
200  break;
201  }
202  return result;
203 }
204 
205 /* allocates and returns a string for reduction r
206  */
207 static string reduction_as_str (reduction r)
208 {
209  string str;
211  "(", omp_operator_str (reduction_op(r)), ":",
213  ")", NULL);
214  pips_debug(5, "finish with string: %s\n", str);
215  return strdup (str);
216 }
217 
218 //***********************************************************Global functions
219 // all global function names start with reductions_
220 
221 
222 //@return a list of expressions with omp pragma for reductions, NULL if nothing
223 //to return
224 //@param l, the loop associated with the statement
225 //@param stmt, the statement to analyzed for reductions, must be a loop
226 //@param srict, when set to true, only loop with one statement are considered
228  list exprs = NIL;
229  // check that reduction as been detected at loop level
230  if (statement_is_reduction (stmt) == true) {
232  // check that the reductions are done on scalars and not arrays
233  if (reductions_on_scalar (rs) == true) {
234  // reset the all reduction flag
236  // check that all the statements of the loop are reductions otherwise, do
237  // not generate omp reduction pragma
238  // the test is too restrictive so need to be improved
239  if(strict)
241  if (all_reduction) {
243  FOREACH (REDUCTION, red, reductions_list(rs)) {
244  exprs = gen_expression_cons (reduction_as_expr (red), exprs);
245  }
246  //secondly get "omp parallel for" as an expr and concatenate
247  list parallel_for = pragma_omp_parallel_for_as_exprs ();
248  exprs = gen_nconc (exprs, parallel_for);
249  }
250  }
251  }
252  pips_debug(5, "finish with pragma\n");
253  return exprs;
254 }
255 
256 ///@return a string with omp pragma for reductions
257 ///@param l, the loop associated with the statement
258 ///@param stmt, the statement to analyzed for reductions, must be a loop
261  // check that reduction as been detected at loop level
262  if (statement_is_reduction (stmt) == true) {
264  // check that the reductions are done on scalars and not arrays
265  if (reductions_on_scalar (rs) == true) {
266  // reset the all reduction flag
268  // check that all the statements of the loop are reductions otherwise, do
269  // not generate omp reduction pragma
270  // the test is too restrictive so need to be improved
272  if (all_reduction == true) {
273  string header = (prettyprint_language_is_fortran_p ()
276  string_buffer_append (buf, strdup (header));
278  FOREACH (REDUCTION, red, reductions_list(rs)) {
280  }
281  }
282  }
283  }
284  string result = string_buffer_to_string (buf);
285  pips_debug(5, "finish with pragma: %s\n", result);
287  return result;
288 }
289 
290 ///@return the new pragma
291 ///@param l, the loop to analyze for omp reduction
292 ///@param exprs, the pragma as a list of expression
294  // the private variables as a list of entites
295  list private = loop_private_variables_as_entites (l, true, true);
296  // add private clause if needed
297  if (gen_length (private) != 0) {
298  expression expr_private = pragma_private_as_expr (private);
299  exprs = gen_expression_cons (expr_private, exprs);
300  }
301  return exprs;
302 }
303 
306  FOREACH(EXTENSION, ext, exts) {
307  if(extension_pragma(ext)) {
308  pragma p = extension_pragma(ext);
309  bool remove=false;
310  if(pragma_string_p(p)) {
311  remove = (strncasecmp("omp", pragma_string(p), 3) == 0);
312  }
313  else if(pragma_expression_p(p)) {
314  list exps = pragma_expression(p);
315  FOREACH(EXPRESSION,exp, exps) {
316  if(expression_call_p(exp)) {
317  call c = expression_call(exp);
318  entity op = call_function(c);
319  const char* omp_entities[] = {
323  NULL
324  };
325  const char *lname = entity_local_name(op);
326  for(const char **iter=omp_entities;*iter;++iter) {
327  if((remove=same_string_p(lname, *iter))) {
328  break;
329  }
330  }
331  }
332  if(remove) break;
333  }
334  }
335  if(remove)
337  }
338  }
339 }
340 
341 /// @brief generate pragma for a reduction as a list of expressions
342 /// @return true if a pragma has been generated
343 /// @param l, the loop to analyze for omp reduction
344 /// @param stmt, the statament where the pragma should be attached
345 /// @param strict, if set to true, only one-liner statements with reductions are handled
347  // the list of expression to generate
348  list exprs = NULL;
349  exprs = reductions_get_omp_pragma_expr(l, stmt, strict);
350  // insert the pragma (if any) as an expression to the current statement
351  if (exprs != NULL) {
352  // remove any previous openmp expression to make sure we do not introduce inconsistency
354  // check if a private clause is needed on top of the reduction clause
355  exprs = omp_append_private_clause (l, exprs);
357  pips_debug (5, "new reduction pragma as an extension added\n");
358  }
359  return (exprs != NULL);
360 }
361 
362 /// @brief generate "pragma omp for" as a list of expressions
363 /// @return true if a pragma has been generated
364 /// @param l, the loop to analyze for omp for
365 /// @param stmt, the statament where the pragma should be attached
367  list exprs = NULL;
369  // the list of expression to generate initialized with
370  // pragma "omp parallel for"
372  exprs = omp_append_private_clause (l, exprs);
373  // insert the pragma as an expression to the current statement
375  pips_debug (5, "new for pragma as an extension added\n");
376  }
377  return (exprs != NULL);
378 }
list gen_expression_cons(expression p, list l)
Definition: ri.c:866
call make_call(entity a1, list a2)
Definition: ri.c:269
syntax make_syntax_call(call _field_)
Definition: ri.c:2500
expression make_expression(syntax a1, normalized a2)
Definition: ri.c:886
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
reference copy_reference(reference p)
REFERENCE.
Definition: ri.c:2047
syntax make_syntax_reference(reference _field_)
Definition: ri.c:2494
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
list loop_private_variables_as_entites(loop obj, bool local, bool index)
Get the variables local or private to a loop.
Definition: loop.c:338
void gen_remove_once(list *pl, const void *o)
Remove the first occurence of o in list pl:
Definition: list.c:691
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
size_t gen_length(const list l)
Definition: list.c:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#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
bool prettyprint_language_is_fortran_p()
Definition: language.c:75
#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
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define same_string_p(s1, s2)
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
int tag
TAG.
Definition: newgen_types.h:92
#define string_undefined
Definition: newgen_types.h:40
string reference_to_string(reference r)
Definition: expression.c:87
static bool statement_is_reduction(statement stmt)
Definition: pragma.c:32
static bool all_reduction
Definition: pragma.c:20
list reductions_get_omp_pragma_expr(loop l, statement stmt, bool strict)
pragma.c
Definition: pragma.c:227
static expression reduction_as_expr(reduction r)
Definition: pragma.c:121
static const string REDUCTION_KEYWORD
Definition: pragma.c:17
static void compute_all_reduction(statement stmt)
remenber if all the statement analazed are reduction since the last reset
Definition: pragma.c:43
static bool reductions_on_scalar(reductions reds)
Definition: pragma.c:49
static string omp_operator_str(reduction_operator o)
Definition: pragma.c:151
static const string OMP_PRAGMA_FOR_HEADER_C
Definition: pragma.c:15
static entity omp_operator_entity(reduction_operator o)
Definition: pragma.c:61
bool omp_pragma_expr_for(loop l, statement stmt)
generate "pragma omp for" as a list of expressions
Definition: pragma.c:366
static void reset_all_reduction(void)
reset the all_reduction flag
Definition: pragma.c:26
string reductions_get_omp_pragma_str(loop l, statement stmt)
Definition: pragma.c:259
static const string OMP_PRAGMA_FOR_HEADER_F
Definition: pragma.c:16
static string reduction_as_str(reduction r)
allocates and returns a string for reduction r
Definition: pragma.c:207
static void statement_remove_omp_clauses(statement stmt)
Definition: pragma.c:304
bool omp_pragma_expr_for_reduction(loop l, statement stmt, bool strict)
generate pragma for a reduction as a list of expressions
Definition: pragma.c:346
static list omp_append_private_clause(loop l, list exprs)
Definition: pragma.c:293
reductions load_printed_reductions(statement)
bool bound_printed_reductions_p(statement)
@ is_reduction_operator_bitwise_xor
@ is_reduction_operator_none
@ is_reduction_operator_min
@ is_reduction_operator_bitwise_and
@ is_reduction_operator_neqv
@ is_reduction_operator_max
@ is_reduction_operator_bitwise_or
@ is_reduction_operator_csum
@ is_reduction_operator_eqv
@ is_reduction_operator_prod
@ is_reduction_operator_or
@ is_reduction_operator_and
@ is_reduction_operator_sum
#define REDUCTION(x)
REDUCTION.
#define reduction_operator_tag(x)
#define reduction_op(x)
#define reduction_reference(x)
#define reductions_list(x)
#define BITWISE_OR_OPERATOR_NAME
#define MAX_OPERATOR_NAME
#define BITWISE_XOR_OPERATOR_NAME
#define C_AND_OPERATOR_NAME
#define EQUIV_OPERATOR_NAME
#define PLUS_OPERATOR_NAME
#define NON_EQUIV_OPERATOR_NAME
#define AND_OPERATOR_NAME
FI: intrinsics are defined at a third place after bootstrap and effects! I guess the name should be d...
#define OMP_OMP_FUNCTION_NAME
#define MULTIPLY_OPERATOR_NAME
#define C_OR_OPERATOR_NAME
#define BITWISE_AND_OPERATOR_NAME
#define OMP_REDUCTION_FUNCTION_NAME
#define OR_OPERATOR_NAME
#define PLUS_C_OPERATOR_NAME
#define OMP_PRIVATE_FUNCTION_NAME
#define MIN_OPERATOR_NAME
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
entity CreateIntrinsic(string name)
this function does not create an intrinsic function because they must all be created beforehand by th...
Definition: entity.c:1311
bool expression_call_p(expression e)
Definition: expression.c:415
call expression_call(expression e)
Definition: expression.c:445
void add_pragma_expr_to_statement(statement st, list l)
Add a pragma as a list of expression to a statement.
Definition: pragma.c:460
list pragma_omp_parallel_for_as_exprs(void)
Definition: pragma.c:236
expression pragma_private_as_expr(list args_ent)
Definition: pragma.c:207
#define normalized_undefined
Definition: ri.h:1745
#define loop_execution(x)
Definition: ri.h:1648
#define pragma_expression_p(x)
Definition: ri.h:2034
#define pragma_string(x)
Definition: ri.h:2033
#define call_function(x)
Definition: ri.h:709
#define pragma_string_p(x)
Definition: ri.h:2031
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define extension_pragma(x)
Definition: ri.h:1295
#define EXTENSION(x)
EXTENSION.
Definition: ri.h:1253
#define entity_undefined
Definition: ri.h:2761
#define pragma_expression(x)
Definition: ri.h:2036
#define reference_indices(x)
Definition: ri.h:2328
#define statement_extensions(x)
Definition: ri.h:2464
#define extensions_extension(x)
Definition: ri.h:1330
#define execution_parallel_p(x)
Definition: ri.h:1211
char * strdup()
static int lname(char *s, int look_for_entry)
check for keywords for subprograms return 0 if comment card, 1 if found name and put in arg string.
Definition: split_file.c:283
static char buf[BSZ]
Definition: split_file.c:157
internally defined structure.
Definition: string_buffer.c:47
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
Definition: statement.c:54
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207