PIPS
gpu_qualify_pointers.c
Go to the documentation of this file.
1 /*
2  $Id: gpu_qualify_pointers.c 23367 2017-02-10 14:35:39Z coelho $
3 
4  Copyright 1989-2016 MINES ParisTech
5 
6  This file is part of PIPS.
7 
8  PIPS is free software: you can redistribute it and/or modify it
9  under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  any later version.
12 
13  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
14  WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  FITNESS FOR A PARTICULAR PURPOSE.
16 
17  See the GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
21 */
22 #ifdef HAVE_CONFIG_H
23 #include "pips_config.h"
24 #endif
25 
26 #include <assert.h>
27 
28 #include "genC.h"
29 #include "linear.h"
30 #include "misc.h"
31 
32 #include "properties.h"
33 #include "resources.h"
34 #include "pipsdbm.h"
35 #include "ri-util.h"
36 
37 /********************************************************************* UTILS */
38 
39 // return whether a variable has a given qualifier
41 {
43  if (qualifier_tag(q) == qt)
44  return true;
45  return false;
46 }
47 
48 static bool variable_is_glopriv(variable var, bool is_glob)
49 {
52 }
53 
54 static void set_variable_qualifier(variable var, bool is_glob)
55 {
56  pips_debug(8, "setting var %p as %s\n", var, is_glob? "global": "private");
57 
58  // check with a user error beforehand...
59  pips_assert(!variable_is_glopriv(var, !is_glob), "cannot be private & global");
60 
61  // skip if already set
62  if (!variable_is_glopriv(var, is_glob))
63  {
66  }
67 }
68 
69 // does it has "global" or "private"?
70 static bool is_glopriv(entity evar, bool is_glob)
71 {
72  pips_assert(entity_variable_p(evar), "qualified entity is a variable");
73  return variable_is_glopriv(type_variable(entity_type(evar)), is_glob);
74 }
75 
76 /* add a qualifier to a variable, which should be a pointer...
77  */
78 static void set_glopriv_qualifier(entity evar, bool is_glob)
79 {
80  pips_debug(3, "marking %s as %s\n",
81  entity_name(evar), is_glob? "global": "private");
82 
83  pips_assert(entity_variable_p(evar), "qualified entity is a variable");
85  "variable must be a pointer type");
86 
87  // check here to have the variable name
88  variable var = type_variable(entity_type(evar));
89  if (variable_is_glopriv(var, !is_glob))
90  pips_user_error("pointer %s cannot be set as %s, it is already %s\n",
91  entity_name(evar),
92  is_glob? "global": "private", is_glob? "private": "global");
93 
94  // do not set if already set. not sure how it could get there...
95  if (!variable_is_glopriv(var, is_glob))
96  set_variable_qualifier(var, is_glob);
97  // else could warn that it get there twice?
98 }
99 
100 static bool is_global(entity evar)
101 {
102  return is_glopriv(evar, true);
103 }
104 
105 static bool is_private(entity evar)
106 {
107  return is_glopriv(evar, false);
108 }
109 
110 static void set_global(entity evar)
111 {
112  set_glopriv_qualifier(evar, true);
113 }
114 
115 static void set_as_private(entity evar)
116 {
117  set_glopriv_qualifier(evar, false);
118 }
119 
120 /************************************************************ GLOBALS/PRIVATES */
121 
122 /* structure to collect whether anything should be qualified as
123  * private or global, for OpenCL 1.X code.
124  */
125 typedef struct
126 {
127  bool changed; // hmmm... iterations
128  // set of anything (entity, expression ...)
131  // may skip
133  hash_table call_sites; // entity -> list<call>
134  // whether to qualify casts
135  bool do_casts;
137 
139 {
140  glopriv_context_t * glc = malloc(sizeof(glopriv_context_t));
141  glc->globals = set_make(set_pointer);
142  glc->privates = set_make(set_pointer);
143  glc->do_call_sites = true;
145  glc->changed = false;
146  glc->do_casts = true;
147  return glc;
148 }
149 
150 static void set_glopriv(
151  glopriv_context_t * glc, void * stuff, bool is_glob,
152  string why)
153 {
154  pips_assert(stuff != NULL, "some stuff");
155 
156  // not necessary
157  if ((is_glob && set_belong_p(glc->globals, stuff)) ||
158  (!is_glob && set_belong_p(glc->privates, stuff)))
159  return;
160 
161  ifdebug(5)
162  {
163  int dom = * (int*) stuff;
164  if (dom == entity_domain)
165  pips_debug(5, "marking entity %s as %s (%s)\n",
166  entity_name((entity) stuff), is_glob? "global": "private", why);
167  else
168  pips_debug(5, "marking %s %p as %s (%s)\n",
169  gen_domain_name(* (int *) stuff),
170  stuff, is_glob? "global": "private", why);
171  }
172 
173  if (is_glob && !set_belong_p(glc->globals, stuff))
174  {
175  set_add_element(glc->globals, glc->globals, stuff);
176  glc->changed = true;
177  }
178  else if (!is_glob && !set_belong_p(glc->privates, stuff))
179  {
180  set_add_element(glc->privates, glc->privates, stuff);
181  glc->changed = true;
182  }
183 }
184 
185 static void free_glopriv(glopriv_context_t ** pglc)
186 {
187  set_free((*pglc)->globals);
188  set_free((*pglc)->privates);
189  HASH_FOREACH(entity, f, list, l, (*pglc)->call_sites) gen_free_list(l);
190  hash_table_free((*pglc)->call_sites);
191  free(*pglc);
192  *pglc = NULL;
193 }
194 
195 // analyse reference as private or global
196 static void glc_ref(reference r, glopriv_context_t * glc)
197 {
198  entity var = reference_variable(r);
199 
200  // nothing to do? should it be marked anyway?
201  if (!(entity_pointer_p(var) || entity_array_p(var)))
202  return;
203 
204  // skip scalars?
205  /*
206  unsigned int ndims =
207  gen_length(variable_dimensions(type_variable(entity_type(var))));
208  if (ndims && gen_length(reference_indices(r)) == ndims)
209  return;
210  */
211 
214 
215  if (is_global(var))
216  {
217  set_glopriv(glc, var, true, "global ref ent");
218  set_glopriv(glc, enclosing, true, "global ref expr");
219  }
220  else if (is_private(var))
221  {
222  set_glopriv(glc, var, false, "private ref ent");
223  set_glopriv(glc, enclosing, false, "private ref expr");
224  }
225  // else do not know
226 }
227 
228 /* ptr = ptr
229  * & reference...
230  * pointer arithmetic with +
231  */
232 static void glc_call(call c, glopriv_context_t * glc)
233 {
234  entity called = call_function(c);
235  list args = call_arguments(c);
236 
237  pips_debug(3, "considering call to %s\n", entity_name(called));
238 
239  if (glc->do_call_sites)
240  {
241  // hm... need only keep track of "user" functions?
242  if (!hash_defined_p(glc->call_sites, called))
243  hash_put(glc->call_sites, called, CONS(call, c, NIL));
244  else
245  hash_update(glc->call_sites, called,
246  CONS(call, c, (list) hash_get(glc->call_sites, called)));
247  }
248 
251 
252  if (ENTITY_ASSIGN_P(called))
253  {
254  pips_assert(gen_length(args) == 2, "2 operands to assign operator '='");
255  expression e1 = EXPRESSION(CAR(args)), e2 = EXPRESSION(CAR(CDR(args)));
257  "assign left operator is a reference");
258 
259  if (expression_pointer_p(e1))
260  {
262  if (set_belong_p(glc->globals, e2))
263  {
264  set_glopriv(glc, var, true, "assign global var ent");
265  set_glopriv(glc, e1, true, "assign global lexpr");
266  if (enclosing)
267  set_glopriv(glc, enclosing, true, "assign global expr");
268  }
269  else if (set_belong_p(glc->privates, e2))
270  {
271  set_glopriv(glc, var, false, "assign private var ent");
272  set_glopriv(glc, e1, false, "assign private lexpr");
273  if (enclosing)
274  set_glopriv(glc, enclosing, false, "assign private expr");
275  }
276  }
277  }
278  else if (enclosing && ENTITY_ADDRESS_OF_P(called))
279  {
280  pips_assert(gen_length(args) == 1, "one reference to &");
281  expression arg = EXPRESSION(CAR(args));
282  if (expression_reference_p(arg))
283  {
285  if (set_belong_p(glc->globals, var))
286  set_glopriv(glc, enclosing, true, "& global expr");
287  else if (set_belong_p(glc->privates, var))
288  set_glopriv(glc, enclosing, false, "& private expr");
289  }
290  }
291  else if (enclosing &&
292  (ENTITY_PLUS_P(called) || ENTITY_PLUS_C_P(called) ||
293  ENTITY_MINUS_P(called) || ENTITY_MINUS_C_P(called)))
294  {
295  // just for pointer arithmetic
296  pips_assert(gen_length(args) == 2, "2 operands to +/- operators");
297  expression e1 = EXPRESSION(CAR(args)), e2 = EXPRESSION(CAR(CDR(args)));
298 
299  // should it detect bad typing, eg "ptr + ptr"? NOT THE POINT!
300 
301  if (set_belong_p(glc->globals, e1) || set_belong_p(glc->globals, e2))
302  set_glopriv(glc, enclosing, true, "global ptr arith expr");
303  else if (set_belong_p(glc->privates, e1) || set_belong_p(glc->privates, e2))
304  set_glopriv(glc, enclosing, false, "private ptr arith expr");
305  }
306  // else: others??
307 }
308 
309 // handle casts
310 // hmmm... type cast on the fly? but is it really needed?
311 static void glc_cast(cast c, glopriv_context_t * glc)
312 {
315 
316  // empty cast? already processed?
317  if (enclosing == NULL ||
318  set_belong_p(glc->globals, enclosing) ||
320  return;
321 
323  type t = cast_type(c);
324  pips_assert(type_variable_p(t), "cast to a variable type");
325 
326  if (set_belong_p(glc->globals, e))
327  {
328  set_glopriv(glc, enclosing, true, "global cast");
329  if (glc->do_casts)
331  }
332  else if (set_belong_p(glc->privates, e))
333  {
334  set_glopriv(glc, enclosing, false, "private cast");
335  if (glc->do_casts)
337  }
338 }
339 
340 static void collect_glopriv(void * stuff, glopriv_context_t * glc)
341 {
342  gen_context_multi_recurse(stuff, glc,
346  NULL);
347 }
348 
350 {
351  pips_debug(2, "collecting glopriv data\n");
352 
353  // process code
354  collect_glopriv(s, glc);
355 
356  // process initializations
358  {
359  value val = entity_initial(var);
360  if (entity_variable_p(var) && entity_pointer_p(var) &&
361  value_expression_p(val))
362  {
364  collect_glopriv(init, glc);
365  if (set_belong_p(glc->globals, init))
366  set_glopriv(glc, var, true, "global init");
367  else if (set_belong_p(glc->privates, init))
368  set_glopriv(glc, var, false, "private init");
369  }
370  }
371 
372  // once is enough for getting calls
373  glc->do_call_sites = false;
374 }
375 
376 /******************************************************************* DRIVERS */
377 
379  entity module,
380  statement code,
381  callees funcs,
382  bool do_casts)
383 {
384  pips_debug(2, "qualifying pointers in module %s\n", entity_name(module));
385 
386  // check for module parameters, mark them if needed
387  // note: there are declarations in the code and in the function signature
388  // should it be set on both?
389  pips_assert(entity_function_p(module), "module must be a function");
390  value val = entity_initial(module);
391  pips_assert(value_code_p(val), "function must have code");
392 
393  // set formal parameters as private or global, in doubt set as global
396  {
397  if (formal_parameter_p(var))
398  {
399  if (entity_pointer_p(var) || entity_array_p(var))
400  {
401  int number = formal_offset(storage_formal(entity_storage(var)));
402  type tn = parameter_type(PARAMETER(gen_nth(number-1, params)));
403  pips_assert(type_variable_p(tn), "formal parameter is a variable");
404  variable fp = type_variable(tn);
405 
406  if (variable_is_glopriv(fp, true))
407  set_global(var);
408  else if (variable_is_glopriv(fp, false))
409  set_as_private(var);
410  else // in doubt, assume it is a global pointer
411  {
412  pips_user_warning("no clue, set formal parameter %s as global\n",
413  entity_name(var));
414  set_variable_qualifier(fp, true);
415  set_global(var);
416  }
417  }
418  }
419  else if (entity_array_p(var))
420  // just a private array declaration
421  set_as_private(var);
422  }
423 
424  // pass through the code
425  glopriv_context_t * glc = new_glopriv();
426  glc->do_casts = do_casts;
427  bool try_again = true;
428  int iteration = 0;
429 
430  while (try_again)
431  {
432  iteration++;
433  pips_debug(3, "propagating privates & globals iteration %d\n", iteration);
434 
435  // update global/private information
436  glc->changed = false;
438 
439  // if something is needed and it is not converging?
440  if (iteration > 1 && !glc->changed)
441  // this may happen if some pointers are not used,
442  // or point to unqualified scalars
443  break;
444 
445  // if changed, more expr may be qualified even if no entity is concerned
446  // this iteration is needed for ensuring that calls are well qualified.
447  try_again = glc->changed;
448 
449  // qualify pointers if possible
451  {
452  if (entity_variable_p(var))
453  {
454  pips_debug(8, "considering variable %s (global=%d, private=%d)\n",
455  entity_name(var), is_global(var), is_private(var));
456  if (!formal_parameter_p(var) &&
457  (entity_pointer_p(var) || entity_array_p(var)) &&
458  !is_private(var) && !is_global(var))
459  {
460  bool
461  var_is_global = set_belong_p(glc->globals, var),
462  var_is_private = set_belong_p(glc->privates, var);
463 
464  // no "else", so as to trigger user errors if need be
465  if (var_is_global)
466  set_global(var);
467  if (var_is_private)
468  set_as_private(var);
469  if (!var_is_global && !var_is_private) // in doubt? set_as_private(var);
470  {
471  pips_debug(5, "in doubt about %s, retrying...\n", entity_name(var));
472  try_again = true;
473  }
474  }
475  }
476  }
477  }
478 
479  // unmarked remaining pointers are expected to be private only
480  // see x/z w/v in "validation/Gpu/glopriv04.c"
482  {
483  if (entity_variable_p(var) && !formal_parameter_p(var) &&
484  (entity_pointer_p(var) || entity_array_p(var)) &&
485  !is_private(var) && !is_global(var))
486  set_as_private(var);
487  }
488 
489  // now mark/check callee parameters
490  FOREACH(string, f, callees_callees(funcs))
491  {
492  pips_debug(3, "updating call to %s\n", f);
495 
496  if (hash_defined_p(glc->call_sites, callee))
497  {
498  FOREACH(call, c, (list) hash_get(glc->call_sites, callee))
499  {
500  pips_assert(call_function(c) == callee, "good function called");
502  "matching #arguments & #parameters");
503  list lp = params;
504  int nparam = 0;
506  {
507  parameter p = PARAMETER(CAR(lp));
508  dummy d = parameter_dummy(p);
509  const string sp = dummy_unknown_p(d)?
510  "?": (const string) entity_local_name(dummy_identifier(d));
511  type te = parameter_type(p);
512  lp = CDR(lp);
513  nparam += 1;
514 
515  if (!pointer_type_p(te) && !array_type_p(te))
516  {
517  pips_debug(5, "skipping non pointer parameter %s:%d (%s)\n",
518  entity_name(callee), nparam, sp);
519  continue;
520  }
521 
522  pips_assert(type_variable_p(te), "type is a variable");
523  variable var = type_variable(te);
524  bool global_expr = set_belong_p(glc->globals, e),
525  private_expr = set_belong_p(glc->privates, e),
526  var_is_global = variable_is_glopriv(var, true),
527  var_is_private = variable_is_glopriv(var, false);
528 
529  if (global_expr && private_expr)
530  // is it possible, or would it be an internal error?
531  pips_user_error("formal parameter \"%s\" (#%d of \"%s\") is both "
532  "private & global\n",
533  sp, nparam, entity_name(callee));
534  if (global_expr && var_is_private)
535  pips_user_error("formal parameter \"%s\" (#%d of \"%s\") is "
536  "already private, cannot switch it to global\n",
537  sp, nparam, entity_name(callee));
538  if (private_expr && var_is_global)
539  pips_user_error("formal parameter \"%s\" (#%d of \"%s\") is "
540  "already global, cannot switch it to private\n",
541  sp, nparam, entity_name(callee));
542 
543  // no else so as to possibly trigger some errors...
544  if (global_expr)
545  set_variable_qualifier(var, true);
546  if (private_expr)
547  set_variable_qualifier(var, false);
548  if (!global_expr && !private_expr) // in doubt, set as private...
549  {
550  pips_debug(5, "setting %s:%d (%s) as private by default\n",
551  entity_name(callee), nparam, sp);
552  set_variable_qualifier(var, false);
553  }
554  }
555  }
556  }
557  // else the callee is not called? unlikely:-)
558  }
559 
560  // cleanup
561  free_glopriv(&glc);
562 }
563 
564 /*
565  gpu_qualify_pointers > MODULE.code
566  > PROGRAM.entities
567  < PROGRAM.entities
568  < MODULE.code
569  < MODULE.callees
570 
571  Some limitations:
572  - it does not deal with pointer in structures or arrays.
573  - ...
574 */
576 {
579  db_get_memory_resource(DBR_CODE, module_name, true));
580  callees funcs = (callees)
581  db_get_memory_resource(DBR_CALLEES, module_name, true);
582 
583  debug_on("GPU_QUALIFY_POINTERS_DEBUG_LEVEL");
584  pips_debug(1, "running on %s", module_name);
585 
588  funcs,
589  get_bool_property("GPU_QUALIFY_POINTERS_DO_CASTS"));
590 
593 
594  debug_off();
595 
598 
599  return true;
600 }
qualifier make_qualifier_private(void)
Definition: ri.c:1957
list gen_qualifier_cons(qualifier p, list l)
Definition: ri.c:1884
qualifier make_qualifier_global(void)
Definition: ri.c:1951
struct paramStruct params
static entity callee
Definition: alias_pairs.c:62
struct _newgen_struct_expression_ * expression
Definition: alias_private.h:21
int dummy
A dummy file, to prevent empty libraries from breaking builds.
Definition: dummy.c:41
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
string gen_domain_name(int t)
GEN_DOMAIN_NAME returns the domain name, and may be used for debug purposes.
Definition: genClib.c:97
void * malloc(YYSIZE_T)
void free(void *)
static void glc_cast(cast c, glopriv_context_t *glc)
static void collect_glopriv(void *stuff, glopriv_context_t *glc)
static void set_glopriv_qualifier(entity evar, bool is_glob)
add a qualifier to a variable, which should be a pointer...
static void set_variable_qualifier(variable var, bool is_glob)
bool gpu_qualify_pointers(const string module_name)
static void glc_call(call c, glopriv_context_t *glc)
ptr = ptr & reference...
static bool variable_is_qualified_as(variable var, enum qualifier_utype qt)
static void free_glopriv(glopriv_context_t **pglc)
static void set_global(entity evar)
static bool is_global(entity evar)
static void collect_glopriv_data(entity f, statement s, glopriv_context_t *glc)
static bool is_glopriv(entity evar, bool is_glob)
static void set_as_private(entity evar)
static glopriv_context_t * new_glopriv(void)
static bool is_private(entity evar)
static bool variable_is_glopriv(variable var, bool is_glob)
static void glc_ref(reference r, glopriv_context_t *glc)
void do_gpu_qualify_pointers(entity module, statement code, callees funcs, bool do_casts)
gpu_qualify_pointers.c
static void set_glopriv(glopriv_context_t *glc, void *stuff, bool is_glob, string why)
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
void gen_context_multi_recurse(void *o, void *context,...)
Multi-recursion with context function visitor.
Definition: genClib.c:3373
gen_chunk * gen_get_current_ancestor(int)
Return current object of that type...
Definition: genClib.c:3587
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
#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
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
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
gen_chunk gen_nth(int n, const list l)
to be used as ENTITY(gen_nth(3, l))...
Definition: list.c:710
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
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:449
void hash_put(hash_table htp, const void *key, const void *val)
This functions stores a couple (key,val) in the hash table pointed to by htp.
Definition: hash.c:364
void hash_update(hash_table htp, const void *key, const void *val)
update key->val in htp, that MUST be pre-existent.
Definition: hash.c:491
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
bool hash_defined_p(const hash_table htp, const void *key)
true if key has e value in htp.
Definition: hash.c:484
#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 pips_user_warning
Definition: misc-local.h:146
#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
#define pips_user_error
Definition: misc-local.h:147
@ hash_pointer
Definition: newgen_hash.h:32
#define HASH_FOREACH(key_type, k, value_type, v, ht)
Definition: newgen_hash.h:71
void set_free(set)
Definition: set.c:332
bool set_belong_p(const set, const void *)
Definition: set.c:194
@ 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
char * string
STRING.
Definition: newgen_types.h:39
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
#define ENTITY_ASSIGN_P(e)
#define ENTITY_MINUS_P(e)
#define ENTITY_PLUS_P(e)
#define ENTITY_PLUS_C_P(e)
#define entity_variable_p(e)
An entity_variable_p(e) may hide a typedef and hence a functional type.
#define ENTITY_MINUS_C_P(e)
#define ENTITY_ADDRESS_OF_P(e)
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
bool entity_array_p(entity e)
Is e a variable with an array type?
Definition: entity.c:754
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
bool entity_function_p(entity e)
Definition: entity.c:724
static int init
Maximal value set for Fortran 77.
Definition: entity.c:320
bool entity_pointer_p(entity e)
Definition: entity.c:745
bool expression_pointer_p(expression e)
we get the type of the expression by calling expression_to_type() which allocates a new one.
Definition: expression.c:506
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
bool array_type_p(type)
Definition: type.c:2942
bool pointer_type_p(type)
Check for scalar pointers.
Definition: type.c:2993
bool formal_parameter_p(entity)
Definition: variable.c:1489
#define formal_offset(x)
Definition: ri.h:1408
#define dummy_identifier(x)
Definition: ri.h:1033
#define value_code_p(x)
Definition: ri.h:3065
#define qualifier_tag(x)
Definition: ri.h:2175
struct _newgen_struct_callees_ * callees
Definition: ri.h:55
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154
#define parameter_dummy(x)
Definition: ri.h:1823
#define parameter_type(x)
Definition: ri.h:1819
#define cast_domain
newgen_call_domain_defined
Definition: ri.h:66
#define call_function(x)
Definition: ri.h:709
#define callees_callees(x)
Definition: ri.h:675
#define reference_variable(x)
Definition: ri.h:2326
#define type_functional(x)
Definition: ri.h:2952
#define type_variable(x)
Definition: ri.h:2949
#define entity_storage(x)
Definition: ri.h:2794
#define code_declarations(x)
Definition: ri.h:784
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
#define storage_formal(x)
Definition: ri.h:2524
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define cast_expression(x)
Definition: ri.h:747
#define dummy_unknown_p(x)
Definition: ri.h:1028
#define reference_domain
newgen_range_domain_defined
Definition: ri.h:338
#define entity_name(x)
Definition: ri.h:2790
#define functional_parameters(x)
Definition: ri.h:1442
#define PARAMETER(x)
PARAMETER.
Definition: ri.h:1788
#define value_code(x)
Definition: ri.h:3067
#define cast_type(x)
Definition: ri.h:745
#define variable_qualifiers(x)
Definition: ri.h:3124
#define call_arguments(x)
Definition: ri.h:711
qualifier_utype
Definition: ri.h:2126
@ is_qualifier_private
Definition: ri.h:2138
@ is_qualifier_global
Definition: ri.h:2136
#define entity_type(x)
Definition: ri.h:2792
#define value_expression_p(x)
Definition: ri.h:3080
#define type_variable_p(x)
Definition: ri.h:2947
#define value_expression(x)
Definition: ri.h:3082
#define entity_domain
newgen_syntax_domain_defined
Definition: ri.h:410
#define entity_initial(x)
Definition: ri.h:2796
int enclosing
This is an horrendous hack.
Definition: rice.c:67
#define ifdebug(n)
Definition: sg.c:47
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
structure to collect whether anything should be qualified as private or global, for OpenCL 1....