PIPS
clone.c
Go to the documentation of this file.
1 /*
2 
3  $Id: clone.c 23065 2016-03-02 09:05:50Z coelho $
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 
25 // do not compile unless required
26 #include "phases.h"
27 #if defined(BUILDER_CLONE) || \
28  defined(BUILDER_CLONE_ONLY) || \
29  defined(BUILDER_CLONE_ON_ARGUMENT) || \
30  defined(BUILDER_CLONE_SUBSTITUTE)
31 
32 #ifdef HAVE_CONFIG_H
33  #include "pips_config.h"
34 #endif
35 /*
36  * Cloning of a subroutine.
37  * debug: CLONE_DEBUG_LEVEL
38  */
39 
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 
44 #include "genC.h"
45 #include "linear.h"
46 
47 #include "misc.h"
48 #include "properties.h"
49 #include "pipsdbm.h"
50 
51 #include "ri.h"
52 #include "effects.h"
53 #include "ri-util.h"
54 #include "workspace-util.h"
55 #include "prettyprint.h" // for text_named_module
56 #include "effects-util.h"
57 
58 #include "pipsmake.h" // add_new_module_from_text
59 #include "preprocessor.h" // compilation_unit_of_module
60 #include "semantics.h" // used
61 #include "callgraph.h" // used
62 
63 #include "syntheses.h"
64 
65 #define DEBUG_ON debug_on("CLONE_DEBUG_LEVEL")
66 #define ALL_DECLS "PRETTYPRINT_ALL_DECLARATIONS"
67 #define STAT_ORDER "PRETTYPRINT_STATEMENT_NUMBER"
68 #define undefined_number_p(n) ((n)==STATEMENT_NUMBER_UNDEFINED)
69 
70 
71 
72 /************************************************** BUILD THE CLONE VERSIONS */
73 
74 /* build a new clone version. if argn is not null, generate a check.
75  */
76 static statement
77 build_statement_for_clone(
78  entity cloned,
79  int argn,
80  int val)
81 {
82  statement stat, check_arg_value;
83 
84  if (argn>0)
85  {
86  entity arg = find_ith_parameter(cloned, argn);
87 
88  /* IF (PARAM#ARGN.NE.VAL) STOP
89  */
90  check_arg_value = test_to_statement
96 
97  statement_comments(check_arg_value) =
99  "!! PIPS: " : "// PIPS: ",
100  entity_user_name(arg),
101  " is assumed a constant reaching value\n", NULL));
102  }
103  else
104  check_arg_value = make_continue_statement(entity_undefined);
105 
106  stat = make_block_statement(
108  );
109 
110  return stat;
111 }
112 
113 /* create an clone, and returns the corresponding entity,
114  * which looks like a not yet parsed routine.
115  * it puts the initial_file for the routine, and updates its user_file.
116  */
117 static entity build_a_clone_for(entity cloned,
118  int argn,
119  int val)
120 {
121  const char* name = entity_local_name(cloned);
122  char* comments, *new_name;
123  entity new_fun;
124  statement stat;
125  bool saved_b1, saved_b2;
126  text t;
127  language l = module_language(cloned);
128 
129  const char* suffix = get_string_property("RSTREAM_CLONE_SUFFIX");
130  int size = 0;
131 
132  pips_debug(2, "building a version of %s with arg %d val=%d\n",
133  name, argn, val);
134 
135  /* builds some kind of module / statement for the clone.
136  */
137  if (empty_string_p(suffix)) {
138  const char *clone_name = get_string_property("CLONE_NAME");
139  new_name = empty_string_p(clone_name) ?
140  build_new_top_level_module_name(name,false) :
141  strdup(clone_name);
142  }
143  else {
144  size = strlen(name) + strlen(suffix) + 1;
145  new_name = (char*)malloc(sizeof(char)*size);
146  new_name[0] = '\0';
147  new_name = strcat(new_name, name);
148  new_name = strcat(new_name, "_");
149  new_name = strcat(new_name, suffix);
150  }
151 
152  new_fun = FindOrCreateEntity(TOP_LEVEL_MODULE_NAME,new_name);
153  entity_type(new_fun) = copy_type(entity_type(cloned));
154  entity_storage(new_fun) = copy_storage(entity_storage(cloned));
155  entity_initial(new_fun) = entity_initial(cloned); /* no copy, reseted later*/
156 
157  saved_b1 = get_bool_property(ALL_DECLS);
158  saved_b2 = get_bool_property(STAT_ORDER);
161 
162  stat = build_statement_for_clone(cloned, argn, val);
163  t = text_named_module(new_fun, cloned, stat);
164 
165 
166  set_bool_property(ALL_DECLS, saved_b1);
167  set_bool_property(STAT_ORDER, saved_b2);
168 
169  /* add some comments before the code.
170  */
171  char *comment_prefix = fortran_module_p(cloned) ? "!!" : "//";
172  comments = strdup(concatenate(
173  comment_prefix,"\n",
174  comment_prefix," PIPS: please caution!\n",
175  comment_prefix,"\n",
176  comment_prefix," this routine has been generated as a clone of ", name, "\n",
177  comment_prefix," the code may change significantly with respect to the original\n",
178  comment_prefix," version, especially after program transformations such as dead\n",
179  comment_prefix," code elimination and partial evaluation, hence the function may\n",
180  comment_prefix," not have the initial behavior, if called under some other context.\n",
181  comment_prefix,"\n", NULL));
182  text_sentences(t) =
185  free_text(t);
186 
187  /* should fix the declarations ... but not the language... */
188  entity_initial(new_fun) =
190  make_code(NIL, strdup(""),
192  NIL,
193  copy_language(l)));
194 
195  free_statement(stat);
196  free(new_name);
197  return new_fun;
198 }
199 
200 
201 /********************************************* STORE ALREADY CLONED VERSIONS */
202 
203 /* already cloned version are kept in a dynamically allocated structure.
204  * it is provided with init/close/get/set functions.
205  */
206 typedef struct
207 {
208  entity the_ref;
209  entity the_clone;
210  int argn;
211  int val;
212 } clone_t;
213 
214 static int clones_index = 0 /* next available */, clones_size = 0;
215 static clone_t * clones = (clone_t*) NULL;
216 
217 #define INITIALIZED pips_assert("clones initialized", clones && clones_size>0)
218 
219 static void
220 init_clone(void)
221 {
222  pips_assert("clones undefined", clones==NULL && clones_size==0);
223  clones_index = 0;
224  clones_size = 10;
225  clones = (clone_t*) malloc(sizeof(clone_t)*clones_size);
226  pips_assert("malloc ok", clones);
227 }
228 
229 static void
230 close_clone(void)
231 {
232  INITIALIZED;
233  free(clones), clones = NULL;
234  clones_size = 0;
235  clones_index = 0;
236 }
237 
238 static entity
239 get_clone(entity the_ref, int argn, int val)
240 {
241  int i;
242  INITIALIZED;
243  pips_debug(8, "get %s %d %d\n", entity_name(the_ref), argn, val);
244  for (i=0; i<clones_index; i++)
245  {
246  if (clones[i].the_ref == the_ref &&
247  clones[i].argn == argn &&
248  clones[i].val == val)
249  return clones[i].the_clone;
250  }
251  return entity_undefined;
252 }
253 
254 static void
255 set_clone(entity the_ref, entity the_clone, int argn, int val)
256 {
257  INITIALIZED;
258  pips_debug(8, "put %s %s %d %d\n",
259  entity_name(the_ref), entity_name(the_clone), argn, val);
260 
261  if (clones_index==clones_size)
262  {
263  clones_size+=10;
264  clones = (clone_t*) realloc(clones, sizeof(clone_t)*clones_size);
265  pips_assert("realloc ok", clones);
266  }
267 
268  clones[clones_index].the_ref = the_ref;
269  clones[clones_index].the_clone = the_clone;
270  clones[clones_index].argn = argn;
271  clones[clones_index].val = val;
272 
273  clones_index++;
274 }
275 
276 
277 /**************************************************** CLONING TRANSFORMATION */
278 
279 /* static structures used for driving the cloning transformation.
280  */
282 
283 static entity module_to_clone = entity_undefined;
284 static int argument_to_clone = 0;
285 static int statement_to_clone = STATEMENT_NUMBER_UNDEFINED;
286 static entity clonee_to_substitute = entity_undefined;
287 static bool some_cloning_performed = false;
288 
289 static void clone_error_handler()
290 {
291  error_reset_stmt_stack();
292  module_to_clone = entity_undefined;
293  argument_to_clone = 0;
294  statement_to_clone = STATEMENT_NUMBER_UNDEFINED;
295  clonee_to_substitute = entity_undefined;
296  some_cloning_performed = false;
297 }
298 
299 /* returns if the expression is a constant, maybe thanks to the preconditions.
300  */
301 static bool
302 this_expression_constant_p(
303  expression e, /* expression to be tested */
304  int * pval /* returned integer value if one was found */)
305 {
306  bool ok = false;
307  if (expression_constant_p(e))
308  {
309  pips_debug(7, "constant expression\n");
310  *pval = expression_to_int(e);
311  ok = true;
312  }
313  else if (expression_reference_p(e))
314  {
315  entity ref;
317  Psysteme prec;
318  Pbase b;
319  Value val;
320 
323  {
324  pips_debug(7, "integer scalar reference\n");
325 
326  /* try with the precondition...
327  */
328  current = stmt_head();
331  b = base_dup(sc_base(prec));
332  vect_erase_var(&b, (Variable) ref);
333  prec = sc_projection_optim_along_vecteur(prec, b);
334  ok = sc_value_of_variable(prec, (Variable) ref, &val);
335  sc_rm(prec), base_rm(b);
336 
337  if (ok) *pval = VALUE_TO_INT(val);
338  }
339  else pips_debug(7, "not an integer scalar reference\n");
340  }
341  else if (expression_call_p(e))
342  {
344  entity fun = call_function(c);
345  value v = entity_initial(fun);
346 
347  if (value_symbolic_p(v) &&
349  {
350  pips_debug(7, "is an int PARAMETER\n");
351  ok = true;
353  }
354  else pips_debug(7, "not a symbolic integer constant\n");
355  }
356  else pips_debug(7, "not a constant nor a reference not a parameter\n");
357 
358  pips_debug(5, "ok = %s, val = %d\n", ok? "TRUE": "FALSE", ok? *pval: 0);
359  return ok;
360 }
361 
362 /* perform a cloning for a given call
363  */
364 static void
365 do_clone(
366  call c, /* call to be replaced */
367  int argn, int val, /* arg number and associated value */
368  entity clonee /* if provided */)
369 {
370  entity cloned = call_function(c);
371  pips_debug(3, "%s cloned on argument %d for value %d\n",
372  entity_name(cloned), argn, val);
373 
374  /* first check whether the cloning was already performed.
375  */
376  if (entity_undefined_p(clonee))
377  {
378  clonee = get_clone(cloned, argn, val);
379  if (clonee==entity_undefined)
380  {
381  clonee = build_a_clone_for(cloned, argn, val);
382  if (argn!=0) set_clone(cloned, clonee, argn, val);
383  }
384  }
385 
386  some_cloning_performed = true;
387  call_function(c) = clonee;
388 }
389 
390 static void
391 clone_rwt(call c)
392 {
393  expression nth_arg;
394  int val = 0;
395 
396  if (call_function(c)!=module_to_clone) return;
397  pips_debug(3, "considering call to %s\n", entity_name(module_to_clone));
398 
399  if (argument_to_clone)
400  {
401  nth_arg = EXPRESSION(gen_nth(argument_to_clone-1, call_arguments(c)));
402  if (this_expression_constant_p(nth_arg, &val)) /* yeah! */
403  do_clone(c, argument_to_clone, val, entity_undefined);
404  }
405  else if (!undefined_number_p(statement_to_clone) &&
406  statement_to_clone==statement_number(stmt_head()))
407  {
408  do_clone(c, 0, 0, clonee_to_substitute);
409  }
410 }
411 
412 /* clone module calls on argument arg in caller.
413  * formal parameter of module number argn must be an integer scalar.
414  * also used for user-directed cloning or substitution.
415  * @return whether okay.
416  */
417 static bool
418 perform_clone(
419  entity module /* the module being cloned */,
420  string caller_name /* the caller of interest */,
421  int argn /* the argument number to be cloned */,
422  int number /* the statement number to clone a call */,
423  entity substitute /* entity to substitute to module */)
424 {
425  statement stat;
426 
427  pips_assert("coherent arguments",
428  (argn!=0 && undefined_number_p(number) &&
429  entity_undefined_p(substitute)) ||
430  (argn==0 && !undefined_number_p(number)));
431 
432  pips_debug(2, "cloning %s in %s on %d\n",
434 
435  stat = (statement) db_get_memory_resource(DBR_CODE, caller_name, true);
436 
437  if (argn!=0)
439  db_get_memory_resource(DBR_PRECONDITIONS, caller_name, true));
440 
441  /* init
442  */
443  make_stmt_stack();
444  module_to_clone = module;
445  argument_to_clone = argn;
446  statement_to_clone = number;
447  clonee_to_substitute = substitute;
448  some_cloning_performed = false;
449 
450  reset_hooks_register(clone_error_handler);
451 
452  /* perform cloning
453  */
454  gen_multi_recurse(stat,
456  call_domain, gen_true, clone_rwt,
457  NULL);
458 
459  /* update CALLEES and CODE if necessary.
460  */
461  if (some_cloning_performed)
462  {
463  DB_PUT_MEMORY_RESOURCE(DBR_CODE, caller_name, stat);
464  DB_PUT_MEMORY_RESOURCE(DBR_CALLEES, caller_name,
465  (char *) compute_callees(stat));
466  }
467 
468  /* close
469  */
470  reset_hooks_unregister(clone_error_handler);
471  module_to_clone = entity_undefined;
472  argument_to_clone = 0;
473  statement_to_clone = STATEMENT_NUMBER_UNDEFINED;
474  clonee_to_substitute = entity_undefined;
475  free_stmt_stack();
476  if (argn!=0) reset_precondition_map();
477 
478  return some_cloning_performed;
479 }
480 
481 
482 /********************************************************************* UTILS */
483 
484 /* global initializations needed */
485 static void
486 set_currents(string name)
487 {
488  entity module;
489  statement stat;
490 
491  pips_debug(1, "considering module %s\n", name);
492 
493  init_clone();
494 
496  pips_assert("is a function", type_functional_p(entity_type(module)));
498 
499  stat = (statement) db_get_memory_resource(DBR_CODE, name, true);
501 }
502 
503 /* global resets
504  */
505 static void
506 reset_currents(const char* name)
507 {
508  close_clone();
511  pips_debug(1, "done with module %s\n", name);
512 }
513 
514 /* check that caller is indeed a caller of name.
515  */
516 static void
517 is_a_caller_or_error(
518  string name,
519  string caller)
520 {
521  callees callers = (callees)db_get_memory_resource(DBR_CALLERS, name, true);
522  MAP(STRING, s,
523  if (same_string_p(s, caller)) return, /* ok */
524  callees_callees(callers));
525 
526  reset_currents(name);
527  pips_user_error("%s is not a caller of %s\n", caller, name);
528 }
529 
530 #define invalid_request_result(s) \
531  (!(s) || string_undefined_p((s) || (strlen((s))==0))
532 
533 static string
534 checked_string_user_request(
535  string fmt, string arg,
536  string error)
537 {
538  string result = user_request(fmt, arg);
539  if (!result || string_undefined_p(result) || (strlen(result)==0))
540  {
541  reset_currents(entity_local_name(get_current_module_entity()));
542  pips_user_error("invalid string for %s\n", error); /* exception */
543  return NULL;
544  }
545  return result;
546 }
547 
548 static int
549 checked_int_user_request(
550  string fmt, string arg,
551  string error)
552 {
553  int result;
554  string si = checked_string_user_request(fmt, arg, error);
555 
556  if (sscanf(si, "%d", &result)!=1)
557  {
558  reset_currents(entity_local_name(get_current_module_entity()));
559  pips_user_error("invalid int for %s\n", error); /* throw */
560  return 0;
561  }
562  free(si);
563  return result;
564 }
565 
566 /******************************************************* PIPSMAKE INTERFACES */
567 
568 #define ARG_TO_CLONE "TRANSFORMATION_CLONE_ON_ARGUMENT"
569 
570 /* clone module name, on the argument specified by property
571  * int TRANSFORMATION_CLONE_ON_ARGUMENT.
572  *
573  * clone_on_argument > CALLERS.callees
574  * > CALLERS.code
575  * < MODULE.code
576  * < MODULE.callers
577  * < MODULE.user_file
578  * < CALLERS.callees
579  * < CALLERS.preconditions
580  * < CALLERS.code
581  */
582 bool clone_on_argument(const string name)
583 {
584  entity module;
585  callees callers; /* warf, warf */
586  int argn;
587 
588  DEBUG_ON;
589  set_currents(name);
591  callers = (callees) db_get_memory_resource(DBR_CALLERS, name, true);
592  argn = get_int_property(ARG_TO_CLONE);
593 
594  if (argn<=0)
595  {
596  do /* perform a user request to get the argument, 0 to stop */
597  {
598  argn = checked_int_user_request("argument of %s to clone", name,
599  "argument number to clone");
600  }
601  while (argn<0);
602  }
603 
604  /* check the argument type: must be an integer scalar */
605  {
606  entity arg = find_ith_parameter(module, argn);
607  type t;
608  variable v;
609 
610  if (entity_undefined_p(arg))
611  {
612  reset_currents(name);
613  pips_user_error("%s: no #%d formal\n", name, argn);
614  return false;
615  }
616 
617  t = entity_type(arg);
618  pips_assert("arg is a variable", type_variable_p(t));
619  v = type_variable(t);
620 
623  {
624  reset_currents(name);
625  pips_user_error("%s: %d formal not a scalar int\n", name, argn);
626  return false;
627  }
628  }
629 
631  perform_clone(module, caller_name, argn,
633  callees_callees(callers));
634 
635  reset_currents(name);
636  debug_off();
637  return true;
638 }
639 
640 /* clone a routine in a caller. the user is requested the caller and
641  * ordering to perform the cloning of that instance. can also be used
642  * to force a function substitution at a call site.
643  *
644  * clone > CALLERS.code
645  * > CALLERS.callees
646  * < MODULE.code
647  * < MODULE.user_file
648  * < CALLERS.code
649  * < CALLERS.callees
650  */
651 static bool
652 clone_or_clone_substitute(
653  string name,
654  bool clone_substitute_p)
655 {
656  entity module, substitute;
657  string caller;
658  int number;
659  bool okay;
660 
661  DEBUG_ON;
662  set_currents(name);
664 
665  caller = checked_string_user_request("%s caller to update?", name,
666  "caller to update");
667 
668  /* checks whether it is an actual caller. */
669  is_a_caller_or_error(name, caller);
670 
671  number = checked_int_user_request(
672  "statement number of %s to clone?", caller,
673  "statement number to clone");
674 
675  if (clone_substitute_p)
676  {
677  string substitute_s =
678  checked_string_user_request("replacement for %s?", name,
679  "replacement function");
680 
681  /* must be a top-level entity or a C static function */
682  substitute = module_name_to_entity(substitute_s);
683  if (entity_undefined_p(substitute) ||
684  !type_functional_p(entity_type(substitute)))
685  {
686  reset_currents(name);
687  pips_user_error("%s is not an existing function\n", substitute_s);
688  return false;
689  }
690  free(substitute_s);
691  }
692  else
693  substitute = entity_undefined;
694 
695  okay = perform_clone(module, caller, 0, number, substitute);
696 
697  if (!okay)
698  {
699  pips_user_warning("substitution of %s by %s at %s:%d not performed\n",
700  name,
701  entity_undefined_p(substitute)?
702  "<none>": entity_local_name(substitute),
703  caller, number);
704  }
705 
706  free(caller);
707  reset_currents(name);
708  debug_off();
709  return okay;
710 }
711 
712 /* clone name in one of its callers/statement number
713  */
714 bool clone(const string name)
715 {
716  return clone_or_clone_substitute(name, false);
717 }
718 
719 /* substitute name in one of its callers/statement number
720  */
721 bool clone_substitute(const string name)
722 {
723  return clone_or_clone_substitute(name, true);
724 }
725 
726 /* use get_current_entity()
727  * and get_current_statement()
728  * to build a new copy entity
729  */
730 static entity
731 clone_current_entity()
732 {
733  return build_a_clone_for(get_current_module_entity(), 0,0);
734 }
735 
736 /* similar to previous clone and clone_substitute
737  * but does not try to make any substitution
738  */
739 #include "preprocessor.h"
740 bool clone_only(const string mod_name)
741 {
742  /* get the resources */
743  statement mod_stmt = (statement)db_get_memory_resource(DBR_CODE, mod_name, true);
746 
747  entity cloned_entity = clone_current_entity();
748 
749  // Used to add the cloned function declaration
751 
752  /* update/release resources */
753  DB_PUT_MEMORY_RESOURCE(DBR_CODE, mod_name,mod_stmt);
754 
757 
758  return !entity_undefined_p(cloned_entity);
759 }
760 
761 #endif // BUILDER_CLONE*
static void stmt_rewrite(statement s)
Definition: graph.c:232
int get_int_property(const string)
call make_call(entity a1, list a2)
Definition: ri.c:269
type copy_type(type p)
TYPE.
Definition: ri.c:2655
statement copy_statement(statement p)
STATEMENT.
Definition: ri.c:2186
value make_value(enum value_utype tag, void *val)
Definition: ri.c:2832
language copy_language(language p)
LANGUAGE.
Definition: ri.c:1202
test make_test(expression a1, statement a2, statement a3)
Definition: ri.c:2607
code make_code(list a1, string a2, sequence a3, list a4, language a5)
Definition: ri.c:353
storage copy_storage(storage p)
STORAGE.
Definition: ri.c:2228
sequence make_sequence(list a)
Definition: ri.c:2125
void free_statement(statement p)
Definition: ri.c:2189
sentence make_sentence(enum sentence_utype tag, void *val)
Definition: text.c:59
void free_text(text p)
Definition: text.c:74
#define error(fun, msg)
NewGen interface with C3 type Psysteme for PIPS project.
Definition: Psc.c:78
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
static const char * caller_name
Definition: alias_check.c:122
static bool stmt_filter(statement s)
modifies global var current_caller_stmt
Definition: alias_pairs.c:222
#define VALUE_TO_INT(val)
int Value
callees compute_callees(const statement stat)
Recompute the callees of a module statement.
Definition: callgraph.c:355
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
#define ALL_DECLS
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
bool empty_string_p(const char *s)
Definition: entity_names.c:239
char * get_string_property(const char *)
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define STRING(x)
Definition: genC.h:87
void * malloc(YYSIZE_T)
void free(void *)
statement make_block_statement(list)
Make a block statement from a list of statement.
Definition: statement.c:616
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
const char * get_current_module_name(void)
Get the name of the current module.
Definition: static.c:121
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_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
#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
gen_chunk gen_nth(int n, const list l)
to be used as ENTITY(gen_nth(3, l))...
Definition: list.c:710
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
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
statement make_continue_statement(entity)
Definition: statement.c:953
bool expression_constant_p(expression)
HPFC module by Fabien COELHO.
Definition: expression.c:2453
bool add_new_module_from_text(const char *module_name, text code_text, bool is_fortran, const char *compilation_unit_name)
Add the new resource files associated to a module with its more-or-less correct code.
Definition: initializer.c:431
#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
string user_request(const char *,...)
void reset_hooks_unregister(reset_func_t)
remove registered cleanup hook.
Definition: reset_hooks.c:73
void reset_hooks_register(reset_func_t)
reset_hooks.c
Definition: reset_hooks.c:44
#define TOP_LEVEL_MODULE_NAME
Module containing the global variables in Fortran and C.
Definition: naming-local.h:101
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define DEFINE_LOCAL_STACK(name, type)
#define same_string_p(s1, s2)
#define string_undefined
Definition: newgen_types.h:40
#define string_undefined_p(s)
Definition: newgen_types.h:41
#define STAT_ORDER
Definition: outlining.c:75
static char * module
Definition: pips.c:74
text text_named_module(entity, entity, statement)
void set_bool_property(const char *, bool)
#define test_to_statement(t)
#define STATEMENT_NUMBER_UNDEFINED
default values
#define call_to_statement(c)
#define module_language(e)
implemented as a macro to allow lhs
#define STOP_FUNCTION_NAME
#define make_statement_list(stats...)
easy list constructor
#define NON_EQUAL_OPERATOR_NAME
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
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 FindOrCreateEntity(const char *package, const char *local_name)
Problem: A functional global entity may be referenced without parenthesis or CALL keyword in a functi...
Definition: entity.c:1586
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
bool fortran_module_p(entity m)
Test if a module is in Fortran.
Definition: entity.c:2799
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
bool expression_call_p(expression e)
Definition: expression.c:415
int expression_to_int(expression exp)
================================================================
Definition: expression.c:2205
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188
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
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 entity_integer_scalar_p(entity)
for variables (like I), not constants (like 1)! use integer_constant_p() for constants
Definition: variable.c:1130
entity find_ith_parameter(entity, int)
Definition: util.c:93
#define type_functional_p(x)
Definition: ri.h:2950
@ is_basic_int
Definition: ri.h:571
struct _newgen_struct_callees_ * callees
Definition: ri.h:55
#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 symbolic_constant(x)
Definition: ri.h:2599
#define constant_int(x)
Definition: ri.h:850
#define basic_tag(x)
Definition: ri.h:613
#define type_variable(x)
Definition: ri.h:2949
#define entity_storage(x)
Definition: ri.h:2794
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
@ is_value_code
Definition: ri.h:3031
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
#define value_symbolic(x)
Definition: ri.h:3070
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define entity_undefined_p(x)
Definition: ri.h:2762
#define entity_undefined
Definition: ri.h:2761
#define constant_int_p(x)
Definition: ri.h:848
#define value_symbolic_p(x)
Definition: ri.h:3068
#define entity_name(x)
Definition: ri.h:2790
#define transformer_relation(x)
Definition: ri.h:2873
#define syntax_call(x)
Definition: ri.h:2736
#define variable_dimensions(x)
Definition: ri.h:3122
#define statement_comments(x)
Definition: ri.h:2456
#define call_arguments(x)
Definition: ri.h:711
#define entity_type(x)
Definition: ri.h:2792
#define statement_number(x)
Definition: ri.h:2452
#define expression_syntax(x)
Definition: ri.h:1247
#define type_variable_p(x)
Definition: ri.h:2947
#define predicate_system(x)
Definition: ri.h:2069
#define variable_basic(x)
Definition: ri.h:3120
#define entity_initial(x)
Definition: ri.h:2796
void sc_rm(Psysteme ps)
void sc_rm(Psysteme ps): liberation de l'espace memoire occupe par le systeme de contraintes ps;
Definition: sc_alloc.c:277
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
bool sc_value_of_variable(Psysteme ps, Variable var, Value *pval)
bool sc_value_for_variable(Psysteme ps, Variable var, Value *pval): examine les egalites du systeme p...
Definition: sc_eval.c:70
char * strdup()
transformer load_statement_precondition(statement)
void reset_precondition_map(void)
void set_precondition_map(statement_mapping)
static bool ok
static size_t current
Definition: string.c:115
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
Definition: statement.c:54
bool clone_on_argument(const string)
clone.c
bool clone(const string)
bool clone_only(const string)
bool clone_substitute(const string)
#define SENTENCE(x)
newgen_unformatted_domain_defined
Definition: text.h:36
#define text_sentences(x)
Definition: text.h:113
@ is_sentence_formatted
Definition: text.h:57
#define base_rm(b)
void * Variable
arithmetique is a requirement for vecteur, but I do not want to inforce it in all pips files....
Definition: vecteur-local.h:60
Pbase base_dup(Pbase b)
Pbase base_dup(Pbase b) Note: this function changes the value of the pointer.
Definition: alloc.c:268
void vect_erase_var(Pvecteur *ppv, Variable v)
void vect_erase_var(Pvecteur * ppv, Variable v): projection du vecteur *ppv selon la direction v (i....
Definition: unaires.c:106
void AddEntityToModuleCompilationUnit(entity e, entity module)
Definition: module.c:301