PIPS
module.c
Go to the documentation of this file.
1 /*
2 
3  $Id: module.c 23412 2017-08-09 15:07:09Z irigoin $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 /* To have asprintf(): */
28 #include <stdlib.h>
29 #include <stdio.h>
30 //#include <stdlib.h> // redundant
31 #include <string.h>
32 
33 #include "linear.h"
34 #include "genC.h"
35 
36 #include "ri-util.h"
37 
38 #include "misc.h"
39 
40 static bool module_coherent_p=true;
42 
43 
44 /* Get a new name for a module built from a prefix.
45 
46  @param prefix is the prefix string
47 
48  @param prevent_suffix is a flag that prevent from adding a "_0" suffix if possible
49 
50  @return the first module name (malloc'd string) of the form
51  "<prefix>_<integer>" that do not correspond to an existing module with
52  integer starting at 0
53  */
54 string
55 build_new_top_level_module_name(const char* prefix, bool prevent_suffix) {
56  string name;
57  int version = 0;
58 
59  if(prevent_suffix) {
60  name = strdup(prefix);
61  }
62 
63  for(;;) {
64  if(!prevent_suffix || version!=0)
65  asprintf(&name, "%s_%d", prefix, version);
66 
68  break;
69 
70  free(name);
71  version++;
72  }
73 
74  return name;
75 }
76 
77 
78 /* Check if the given module entity is a static module.
79  */
82 }
83 
84 
85 /* Check if the given module entity is a compilation unit.
86  */
88  if (e == entity_undefined) return false;
90 }
91 
92 
93 bool
95 entity v;
96 entity m;
97 {
98  bool in_module_1 =
101 
102  bool in_module_2 = entity_is_argument_p(v,decl);
103 
104  ifdebug(8) {
105  if (!in_module_1 || !in_module_2) {
106  pips_debug(8, "variable %s not in declarations of %s\n",
107  entity_name(v),entity_name(m));
108  dump_arguments(decl);
109  }
110  }
111  return (in_module_1 && in_module_2);
112 }
113 
114 
115 void
117 {
118 
120  { module_coherent_p = false;
121  fprintf(stderr,
122  "variable non declaree %s\n",
124  }
125 }
126 
127 void
129 {
130 
133  { module_coherent_p = false;
134  ifdebug(4) fprintf(stderr,
135  "variable non declaree %s\n",
137  }
138  }
139 }
140 
141 void
143 {
145  /* type t = entity_type(var); */
146 
148  {
150  code ce = value_code(val);
151  list decl = code_declarations (ce);
153  string name=strdup(concatenate(
156  entity_local_name(var),
157  NULL));
159  {
160  pips_debug(8, "ajout de la variable symbolique %s au module %s\n",
162 
163  ent = make_entity(name,
164  copy_type(entity_type(var)),
166  copy_value(entity_initial(var)));
167 
168  code_declarations(ce) = gen_nconc(decl,
169  CONS(ENTITY, ent, NIL));
170  }
171  }
172 }
173 
174 void
176 {
179  code ce = value_code(val);
180  list decl = code_declarations (ce);
184  entity_local_name(call_function(c)), NULL));
185  if ((ent = gen_find_tabulated(name,entity_domain)) == entity_undefined) {
186  ifdebug(8)
187  (void) fprintf(stderr,"ajout de la variable symbolique %s au module %s\n",
190 
191  ent = make_entity( name,
195 
196  code_declarations(ce) = gen_nconc(decl,
197  CONS(ENTITY, ent, NIL));
198  }
199  }
200 }
201 
202 bool
204 {
205  module_coherent_p = true;
209  gen_true,
211  module_coherent_p = true;
213  call_domain,
214  gen_true,
217  return module_coherent_p;
218 }
219 
220 /****************************************************** DECLARATION COMMENTS */
221 
222 /* Look for the end of header comments: */
223 static string
224 get_end_of_header_comments(string the_comments)
225 {
226  string end_of_comment = the_comments;
227 
228  for(;;) {
229  string next_line;
230  /* If we are at the end of string or the line is not a comment
231  (it must be a PROGRAM, FUNCTION,... line), it is the end of
232  the header comment: */
233  if (!comment_string_p(end_of_comment))
234  break;
235 
236  if ((next_line = strchr(end_of_comment, '\n')) != NULL
237  || *end_of_comment != '\0')
238  /* Look for next line */
239  end_of_comment = next_line + 1;
240  else
241  /* No return char: it is the last line and it is a
242  comment... Should never happend in a real program
243  without any useful header! */
244  pips_assert("get_end_of_header_comments found only comments!",
245  false);
246  }
247  return end_of_comment;
248 }
249 
250 
251 /* Get the header comments (before PROGRAM, FUNCTION,...) from the
252  text declaration: */
253 sentence
255 {
256  int length;
257  string end_of_comment;
258  string extracted_comment;
259  /* Get the textual header: */
260  string the_comments = code_decls_text(entity_code(module));
261 
262  end_of_comment = get_end_of_header_comments(the_comments);
263  /* Keep room for the trailing '\0': */
264  length = end_of_comment - the_comments;
265  extracted_comment = (string) malloc(length + 1);
266  (void) strncpy(extracted_comment, the_comments, length);
267  extracted_comment[length] = '\0';
268  return make_sentence(is_sentence_formatted, extracted_comment);
269 }
270 
271 
272 /* Get all the declaration comments, that are comments from the
273  PROGRAM, FUNCTION,... stuff up to the end of the declarations: */
274 sentence
276 {
277  string comment;
278  string old_extracted_comments;
279  string extracted_comments = strdup("");
280  /* Get the textual header: */
281  string the_comments = code_decls_text(entity_code(module));
282 
283  comment = get_end_of_header_comments(the_comments);
284  /* Now, gather all the comments: */
285  for(;;) {
286  string next_line;
287  if (*comment == '\0')
288  break;
289  next_line = strchr(comment, '\n');
290  if (comment_string_p(comment)) {
291  string the_comment;
292  /* Add it to the extracted_comments: */
293  if (next_line == NULL)
294  /* There is no newline, so this is the last
295  comment line: */
296  the_comment = strdup(comment);
297  else {
298  /* Build a string that holds the comment: */
299  the_comment = (string) malloc(next_line - comment + 2);
300  (void) strncpy(the_comment, comment, next_line - comment + 1);
301  the_comment[next_line - comment + 1] = '\0';
302  }
303  old_extracted_comments = extracted_comments;
304  extracted_comments = strdup(concatenate(old_extracted_comments,
305  the_comment,
306  NULL));
307  free(old_extracted_comments);
308  free(the_comment);
309  }
310  /* Have a look to next line if any... */
311  if (next_line == NULL)
312  break;
313  comment = next_line + 1;
314  }
315 
316  return make_sentence(is_sentence_formatted, extracted_comments);
317 }
318 
319 /* list module_formal_parameters(entity func)
320  * input : an entity representing a function.
321  * output : the ordered list (of entities) of parameters of the function "func".
322  * modifies : nothing.
323  * comment : Made from "entity_to_formal_integer_parameters()" that considers
324  * only integer variables.
325  */
326 list
328 {
329  list formals = NIL;
330  list decl = list_undefined;
331 
332  pips_assert("func must be a module",entity_module_p(func));
333 
334  decl = code_declarations(entity_code(func));
335  FOREACH(ENTITY, e, decl)
336  {
337  /* Dummy parameters should have been filtered out of the
338  declarations by the parser, but let's be careful here. As a
339  consequence, dummy parameters cannot be retrieved, except
340  thru the type. */
344  formals = CONS(ENTITY, e, formals);
345  }
346 
347  return gen_nreverse(formals);
348 }
349 
350 /* Number of user declaration lines for a module */
351 int
353 {
354  value v = entity_initial(func);
355  code c = code_undefined;
356  int length = 0;
357 
358  if(!value_undefined_p(v)) {
359  if(value_code_p(v)) {
360  string s = string_undefined;
361 
362  c = value_code(v);
363  s = code_decls_text(c);
364  if(string_undefined_p(s)) {
365  /* Is it allowed? The declaration text may be destroyed or
366  * may not exist when a module is synthesized or heavily
367  * transformed.
368  */
369  length = 0;
370  }
371  else {
372  char l;
373  while((l=*s++)!= '\0')
374  if(l=='\n')
375  length++;
376  }
377  }
378  else {
379  pips_internal_error("Entity %s is not a module",
380  entity_name(func));
381  }
382  }
383  else {
384  /* Entity func has not been parsed yet */
385  length = -1;
386  }
387 
388  return length;
389 }
390 
391 /* Find all references in the declaration list */
393 {
394  list srl = NIL;
395 
396  /* FI: for efficiency, the type cache used in
397  type_supporting_references() should be moved up here */
398  FOREACH(ENTITY, v,dl)
399  {
400  if( ! entity_special_area_p(v))
401  {
402  type t = entity_type(v);
403  /* FI: we should also look up the initial values */
404  srl = type_supporting_references(srl, t);
405  }
406  }
407 
408  return srl;
409 }
410 
411 
412 
413 /* The function itself is not in its declarations. Maybe, it should be
414  * changed in the parser?
415  *
416  * A new list is allocated to avoid sharing with code_declarations.
417  */
418 
420 {
422  return dl;
423 }
424 
425 ␌
426 /* Simplified versions of c_module_p() and fortran_module_p().
427  *
428  * They cannot be used before the parsing is advanced unlike the other
429  * above two functions located in preprocessor, but they only require
430  * stuff from ri-util.
431 */
432 static bool x_language_module_p(entity m, unsigned int x)
433 {
434  bool is_x = true;
435  value mv = entity_initial(m);
436 
437  if(value_code_p(mv)) {
438  code c = value_code(mv);
439  is_x = language_tag(code_language(c))==x;
440  }
441  else
442  is_x = false;
443 
444  return is_x;
445 }
446 
448 {
450 }
451 
453 {
455 }
456 
458 {
460 }
461 ␌
462 /* Returns the entity rv that carries the value returned by module m,
463  * when m is not a C void function or a Fortran subroutine. If safe_p,
464  * abort if the function is void. Otherwise, return an
465  * undefined_entity.
466  *
467  * rv is supposed to be allocated early by the parser.
468  */
470 {
474  if(safe_p)
475  pips_user_error("A return value is requested for compilation unit"
476  " \"%s\".\n", entity_user_name(m));
477  else
478  rv = entity_undefined;
479  }
480  else if(type_functional_p(ft)) {
483  if(type_void_p(r)) {
484  if(safe_p)
485  pips_user_error("A return value is used for void function \"%s\".\n",
486  entity_user_name(m));
487  else
488  rv = entity_undefined;
489  }
490  else {
491  const char* mn = entity_local_name(m);
492  rv = FindEntity(mn, mn);
493 
494  pips_assert("rv is defined", entity_defined_p(rv));
495  }
496  }
497  else
498  pips_internal_error("Return value requested for non-functional object"
499  " \"%s\".\n", entity_user_name(m));
500 
501  return rv;
502 }
503 
504 /* Returns the entity rv that carries the value returned by module m,
505  * when m is not a C void function or a Fortran subroutine.
506  *
507  * rv is supposed to be allocated early by the parser.
508  */
510 {
511  return generic_function_to_return_value(m, true);
512 }
513 
514 /* Same as function_to_return_value(), but returns value_undefined
515  when m is a C void function or a Fortran subroutine. */
517 {
518  return generic_function_to_return_value(m, false);
519 }
520 
521 /* Is entity v the return value of some function? */
523 {
524  bool return_p = strcmp(entity_module_name(v), entity_user_name(v))==0;
525  return return_p;
526 }
527 
528 /* Is entity v the return value of function f? */
530 {
531  bool return_p = strcmp(entity_module_name(v), entity_user_name(v))==0
532  && strcmp(entity_module_name(v), entity_user_name(f))==0;
533  return return_p;
534 }
535 
536 /* Check if m is a C void function or a Fortran subroutine. No
537  information about m is available when false is returned. */
539 {
540  type ft = ultimate_type(entity_type(m));
541  bool void_p = false;
542 
543  if(type_functional_p(ft)) {
545  type r = functional_result(f);
546  if(type_void_p(r)) {
547  void_p = true;
548  }
549  }
550 
551  return void_p;
552 }
553 
554 /* Build a list of functions from a string s containing SPACE
555  * separated function names.
556  *
557  * Beware of ambiguities that static function names may cause.
558  *
559  * See also string_to_entities() and a similar piece of code in
560  * inlining.c that was used to code this function.
561  */
563 {
564  list ml = NIL; // module list
565  string ds = strdup(s);
566 
567  string c_name= NULL;
568  for(c_name = strtok(ds," ") ;
569  c_name ;
570  c_name=strtok(NULL," ") ) {
572  if(entity_undefined_p(m))
573  /* FI: warning at a very low level, with no information about
574  the context. Might be better to return list_undefined on a
575  conversion failure? */
576  pips_user_warning("No function found for \"%s\".\n", c_name);
577  else
578  ml = CONS(ENTITY, m, ml);
579  }
580  free(ds);
581  return ml;
582 }
583 /*
584  * that is all
585  */
type copy_type(type p)
TYPE.
Definition: ri.c:2655
bool entity_defined_p(entity p)
Definition: ri.c:2534
value copy_value(value p)
VALUE.
Definition: ri.c:2784
storage copy_storage(storage p)
STORAGE.
Definition: ri.c:2228
sentence make_sentence(enum sentence_utype tag, void *val)
Definition: text.c:59
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
bool entity_is_argument_p(entity e, cons *args)
Definition: arguments.c:150
void dump_arguments(cons *args)
entity_name is a macro, hence the code replication
Definition: arguments.c:69
bool static_module_name_p(const char *name)
Check if the given name is a static module name.
Definition: entity_names.c:122
bool compilation_unit_p(const char *module_name)
The names of PIPS entities carry information about their nature.
Definition: entity_names.c:56
static void comment(string_buffer code, spoc_hardware_type hw, dagvtx v, int stage, int side, bool flip)
Definition: freia_spoc.c:52
void * malloc(YYSIZE_T)
void free(void *)
void gen_multi_recurse(void *o,...)
Multi recursion visitor function.
Definition: genClib.c:3428
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
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
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h: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
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
#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 asprintf
Definition: misc-local.h:225
#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 pips_user_error
Definition: misc-local.h:147
#define MODULE_SEP_STRING
Definition: naming-local.h:30
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define same_string_p(s1, s2)
void * gen_find_tabulated(const char *, int)
Definition: tabulated.c:218
#define string_undefined
Definition: newgen_types.h:40
char * string
STRING.
Definition: newgen_types.h:39
#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
static const char * prefix
#define make_entity(n, t, s, i)
#define entity_declarations(e)
MISC: newgen shorthands.
bool entity_special_area_p(entity e)
Definition: area.c:154
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
entity FindEntity(const char *package, const char *name)
Retrieve an entity from its package/module name and its local name.
Definition: entity.c:1503
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 dummy_parameter_entity_p(entity p)
is p a dummy parameter?
Definition: entity.c:1941
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
code entity_code(entity e)
Definition: entity.c:1098
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
bool entity_module_p(entity e)
Definition: entity.c:683
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
static string get_end_of_header_comments(string the_comments)
Look for the end of header comments:
Definition: module.c:224
entity any_function_to_return_value(entity m)
Same as function_to_return_value(), but returns value_undefined when m is a C void function or a Fort...
Definition: module.c:516
bool variable_declaration_coherency_p(entity module, statement st)
Definition: module.c:203
list module_all_declarations(entity m)
The function itself is not in its declarations.
Definition: module.c:419
sentence get_header_comments(entity module)
Get the header comments (before PROGRAM, FUNCTION,...) from the text declaration:
Definition: module.c:254
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
bool c_language_module_p(entity m)
Definition: module.c:447
list string_to_user_modules(const char *s)
Build a list of functions from a string s containing SPACE separated function names.
Definition: module.c:562
void symbolic_constant_declaration_verify(call c)
Definition: module.c:128
list module_formal_parameters(entity func)
list module_formal_parameters(entity func) input : an entity representing a function.
Definition: module.c:327
void variable_declaration_verify(reference ref)
Definition: module.c:116
static bool module_coherent_p
To have asprintf():
Definition: module.c:40
void add_non_declared_reference_to_declaration(reference ref)
Definition: module.c:142
entity generic_function_to_return_value(entity m, bool safe_p)
Returns the entity rv that carries the value returned by module m, when m is not a C void function or...
Definition: module.c:469
bool static_module_p(entity e)
Check if the given module entity is a static module.
Definition: module.c:80
bool return_value_p(entity v)
Is entity v the return value of some function?
Definition: module.c:522
bool void_function_p(entity m)
Check if m is a C void function or a Fortran subroutine.
Definition: module.c:538
entity function_to_return_value(entity m)
Returns the entity rv that carries the value returned by module m, when m is not a C void function or...
Definition: module.c:509
bool fortran95_language_module_p(entity m)
Definition: module.c:457
void add_symbolic_constant_to_declaration(call c)
Definition: module.c:175
bool fortran_language_module_p(entity m)
Definition: module.c:452
int module_to_declaration_length(entity func)
Number of user declaration lines for a module.
Definition: module.c:352
bool function_return_value_p(entity v, entity f)
Is entity v the return value of function f?
Definition: module.c:529
bool compilation_unit_entity_p(entity e)
Check if the given module entity is a compilation unit.
Definition: module.c:87
static bool x_language_module_p(entity m, unsigned int x)
Simplified versions of c_module_p() and fortran_module_p().
Definition: module.c:432
list declaration_supporting_references(list dl)
Find all references in the declaration list.
Definition: module.c:392
sentence get_declaration_comments(entity module)
Get all the declaration comments, that are comments from the PROGRAM, FUNCTION,...
Definition: module.c:275
bool variable_in_module_p2(entity v, entity m)
Definition: module.c:94
static entity checked_module
Definition: module.c:41
type ultimate_type(type)
Definition: type.c:3466
bool comment_string_p(const string)
Test if a string can be a Fortran 77 comment:
Definition: util.c:159
list type_supporting_references(list, type)
Definition: type.c:4700
type entity_basic_concrete_type(entity)
retrieves or computes and then returns the basic concrete type of an entity
Definition: type.c:3677
type compute_basic_concrete_type(type)
computes a new type which is the basic concrete type of the input type (this new type is not stored i...
Definition: type.c:3556
#define type_functional_p(x)
Definition: ri.h:2950
#define value_undefined_p(x)
Definition: ri.h:3017
#define value_code_p(x)
Definition: ri.h:3065
#define functional_result(x)
Definition: ri.h:1444
#define code_undefined
Definition: ri.h:757
#define storage_formal_p(x)
Definition: ri.h:2522
#define call_function(x)
Definition: ri.h:709
#define reference_variable(x)
Definition: ri.h:2326
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define type_functional(x)
Definition: ri.h:2952
#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 entity_undefined_p(x)
Definition: ri.h:2762
#define reference_domain
newgen_range_domain_defined
Definition: ri.h:338
#define entity_undefined
Definition: ri.h:2761
#define value_symbolic_p(x)
Definition: ri.h:3068
#define type_void_p(x)
Definition: ri.h:2959
#define entity_name(x)
Definition: ri.h:2790
#define value_code(x)
Definition: ri.h:3067
#define value_reference_p(x)
Definition: ri.h:3083
#define code_decls_text(x)
Definition: ri.h:786
#define entity_type(x)
Definition: ri.h:2792
#define code_language(x)
Definition: ri.h:792
#define language_tag(x)
Definition: ri.h:1590
@ is_language_fortran
Definition: ri.h:1566
@ is_language_fortran95
Definition: ri.h:1568
@ is_language_c
Definition: ri.h:1567
#define entity_domain
newgen_syntax_domain_defined
Definition: ri.h:410
#define entity_initial(x)
Definition: ri.h:2796
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
#define ifdebug(n)
Definition: sg.c:47
static char * x
Definition: split_file.c:159
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
@ is_sentence_formatted
Definition: text.h:57