PIPS
freeze_variables.c
Go to the documentation of this file.
1 /*
2 
3  $Id: freeze_variables.c 23495 2018-10-24 09:19:47Z 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 #ifdef BUILDER_FREEZE_VARIABLES
28 
29 #ifdef HAVE_CONFIG_H
30  #include "pips_config.h"
31 #endif
32 
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 
37 #include "genC.h"
38 #include "linear.h"
39 
40 #include "misc.h"
41 #include "pipsdbm.h"
42 
43 #include "ri.h"
44 #include "effects.h"
45 #include "ri-util.h"
46 #include "effects-util.h"
47 
48 #include "effects-generic.h" // used
49 #include "control.h" // module_reorder
50 
51 typedef struct { list old, new; } entity_lists;
52 
53 static bool rw_effect_on_variable_p(list efs, entity var, bool b)
54 {
55  bool readeff = false;
56  list le = NIL;
57 
58  for( le =efs ; !ENDP(le ) && !readeff ; POP(le) ) {
59  effect e= EFFECT(CAR(le));
61  entity v = reference_variable(r);
62  if ((v==var) &&
63  ((b && action_read_p(effect_action(e))) ||
64  (!b && action_write_p(effect_action(e)))))
65  readeff= true;
66  }
67  return readeff;
68 }
69 
70 static bool entity_in_call_arguments_p(entity ent, call c)
71 {
72  list le=call_arguments(c);
73  bool seen=false;
74  for( ; !ENDP(le ) && !seen ; POP(le) ) {
75  expression e= EXPRESSION(CAR(le));
78  seen = true;
79  }
80  return seen;
81 }
82 
83 
84 static void substitute_entity_in_call_arguments(entity old, entity new, call c)
85 {
86 
87  list args = call_arguments(c);
88  list tempargs = NIL;
89  while (!ENDP(args))
90  {
91  expression exp = EXPRESSION(CAR(args));
93  tempargs = gen_nconc(tempargs,CONS(EXPRESSION,temp,NIL));
94  args = CDR(args);
95  }
96  call_arguments(c) = tempargs;
97 }
98 
99 static void freeze_variables_in_statement(statement s, entity_lists * el)
100 {
102  bool read_eff_on_var_already_seen = false;
103  bool READ_EFF = true;
104  list new_entl = el->new;
105  list old_entl = el->old;
106  list first_st = NIL;
107  list last_st = NIL;
108  bool st_to_insert_before= false;
109  bool one_entity_in_args = false;
110  if (statement_call_p(s))
111  {
112  entity lb = statement_label(s);
113 
114  // scan the lists of entities to freeze
115  // some memory leaks should be fixed... FC.
116  for (; !ENDP(old_entl) && !ENDP(new_entl);POP(old_entl), POP(new_entl))
117  {
118  entity ent = ENTITY(CAR(old_entl));
119  entity new_ent = ENTITY(CAR(new_entl));
120  bool this_entity_in_args = false;
121  string strg =
122  strdup(concatenate("'Frozen variable ",
123  entity_local_name(ent),
124  " in ",
126  " changed'",(char *) NULL));
127  one_entity_in_args = one_entity_in_args ||
128  (this_entity_in_args =
129  entity_in_call_arguments_p(ent,
131  read_eff_on_var_already_seen=false;
132  if (this_entity_in_args) {
133  MAP(EFFECT, eff, {
135  entity v = reference_variable(r);
136  if (v == ent) {
137  if (action_write_p(effect_action(eff))) {
138  call c1=call_undefined;
139  test t1=test_undefined;
145  if (read_eff_on_var_already_seen
146  || rw_effect_on_variable_p(efs,ent,READ_EFF)) {
147  /* if call and READ effect on ent, initialize new_ent=ent*/
150  i1 = make_assign_instruction(e1,e2);
153  first_st=CONS(STATEMENT,s1, first_st);
154  st_to_insert_before = true;
155  }
156  /* subtitute ent with new_ent in assignment or call */
158  substitute_entity_in_call_arguments(ent, new_ent,c1);
159 
160  /* insert after: if (new_ent.NE.ent) STOP */
164  make_expression_list(e1,e2));
165 
168  t1 = make_test(e3,
169  make_stop_statement(strg),
171  s1 =test_to_statement(t1);
172  last_st=CONS(STATEMENT,s1, last_st);
173  }
174  else read_eff_on_var_already_seen = true;
175  }
176  }, efs);
177  }
178  }
179  if (one_entity_in_args){
180  if (st_to_insert_before) {
181  MAPL(st, {
182  insert_statement(s, STATEMENT(CAR(st)),true);
183  if (ENDP(CDR(st))) statement_label(STATEMENT(CAR(st)))=lb;
184  }, first_st);
185  }
186  MAPL(st, {
187  insert_statement(s, STATEMENT(CAR(st)),false);
188  }, last_st);
189  }
190 
191  }
192 }
193 
194 static bool initialized_variable_p(entity e)
195 {
196  return variable_static_p(e);
197 }
198 
199 bool freeze_variables(char *mod_name)
200 {
201  entity module;
202  list frozen_entities = NIL;
203  list cumu_eff=NIL;
204  string names="";
205  string rep="";
206  bool WRITE_EFF = false;
207  entity_lists new_le = {NIL,NIL};
208  statement mod_stmt = (statement) db_get_memory_resource(DBR_CODE, mod_name, true);
209  /* INITIALISATION */
210  if (!statement_undefined_p(mod_stmt)) {
212  module =module_name_to_entity(mod_name);
215  db_get_memory_resource(DBR_PROPER_EFFECTS,
216  mod_name,
217  true));
219  db_get_memory_resource(DBR_CUMULATED_EFFECTS,
220  mod_name,
221  true));
222 
223  cumu_eff = load_cumulated_rw_effects_list(mod_stmt);
224  /* USER REQUEST */
225  rep = user_request("Which variables do you want to freeze?\n",mod_name);
226  if (rep[0] == '\0') {
227  user_log("No variable to freeze\n");
228  return false;
229  }
230  else names=rep;
231  frozen_entities = string_to_entity_list(mod_name,names);
232 
233  /* build the list of scalar entities to freeze in the module*/
234  MAP(ENTITY,ent, {
235  if (rw_effect_on_variable_p(cumu_eff,ent,WRITE_EFF)) {
237  pips_assert("entity to freeze is a scalar variable",
238  (type_variable_p(entity_type(ent)) ||
240  if (!variable_in_common_p(ent))
241  user_log("Variable %s to freeze is not in a COMMON \n",
242  entity_local_name(ent));
243  if (!initialized_variable_p(ent))
244  user_log("Variable %s to freeze is not present in a DATA \n",
245  entity_local_name(ent));
247  new_le.old= CONS(ENTITY, ent, new_le.old);
248  new_le.new = CONS(ENTITY,
250  new_le.new);
251  }
252  },
253  frozen_entities);
254 
255  /* recurse on module statements */
256  if (!ENDP(new_le.old))
257  gen_context_recurse(mod_stmt, &new_le,
258  statement_domain, gen_true2, freeze_variables_in_statement);
259 
260  gen_free_list(new_le.new);
261  pips_assert("Statement is consistent after FREEZING VARIABLES",
262  statement_consistent_p(mod_stmt));
263 
264  /* Reorder the module, because new statements have been added */
265  module_reorder(mod_stmt);
266  DB_PUT_MEMORY_RESOURCE(DBR_CODE, mod_name,mod_stmt);
271  }
272  return true;
273 }
274 
275 #endif // BUILDER_FREEZE_VARIABLES
static hash_table seen
static function to store whether a module has been seen during the recursive generation of the daVinc...
Definition: graph.c:85
void user_log(const char *format,...)
Definition: message.c:234
call make_call(entity a1, list a2)
Definition: ri.c:269
expression make_expression(syntax a1, normalized a2)
Definition: ri.c:886
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
bool statement_consistent_p(statement p)
Definition: ri.c:2195
test make_test(expression a1, statement a2, statement a3)
Definition: ri.c:2607
reference copy_reference(reference p)
REFERENCE.
Definition: ri.c:2047
syntax make_syntax(enum syntax_utype tag, void *val)
Definition: ri.c:2491
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
list load_proper_rw_effects_list(statement)
void reset_proper_rw_effects(void)
void set_proper_rw_effects(statement_effects)
void set_cumulated_rw_effects(statement_effects)
list load_cumulated_rw_effects_list(statement)
void reset_cumulated_rw_effects(void)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define effect_action(x)
Definition: effects.h:642
#define action_write_p(x)
Definition: effects.h:314
#define action_read_p(x)
Definition: effects.h:311
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
Definition: genC.h:285
statement make_block_statement(list)
Make a block statement from a list of statement.
Definition: statement.c:616
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
Definition: statement.c:597
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
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
bool gen_true2(__attribute__((unused)) gen_chunk *u1, __attribute__((unused)) void *u2)
Definition: genClib.c:2785
instruction make_assign_instruction(expression l, expression r)
Definition: instruction.c:87
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#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 CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define MAPL(_map_list_cp, _code, _l)
Apply some code on the addresses of all the elements of a list.
Definition: newgen_list.h:203
#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
bool statement_call_p(statement)
Definition: statement.c:364
statement make_stop_statement(string)
This function returns a Fortran stop statement with an error message.
Definition: statement.c:908
void insert_statement(statement, statement, bool)
This is the normal entry point.
Definition: statement.c:2570
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
string user_request(const char *,...)
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
static char * module
Definition: pips.c:74
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
#define make_expression_list(stats...)
#define test_to_statement(t)
#define NON_EQUAL_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
list string_to_entity_list(string module, string names)
of entity
Definition: entity.c:1887
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
entity entity_empty_label(void)
Definition: entity.c:1105
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
expression reference_to_expression(reference r)
Definition: expression.c:196
expression substitute_entity_in_expression(entity old, entity new, expression e)
This function replaces all the occurences of an old entity in the expression exp by the new entity.
Definition: expression.c:2792
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
entity make_new_scalar_variable(entity, basic)
Definition: variable.c:741
bool variable_in_common_p(entity)
true if v is in a common.
Definition: variable.c:1570
bool variable_static_p(entity)
true if v appears in a SAVE statement, or in a DATA statement, or is declared static i C.
Definition: variable.c:1579
#define normalized_undefined
Definition: ri.h:1745
#define reference_variable(x)
Definition: ri.h:2326
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define test_undefined
Definition: ri.h:2808
#define type_variable(x)
Definition: ri.h:2949
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
@ is_syntax_call
Definition: ri.h:2693
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define instruction_undefined
Definition: ri.h:1454
#define statement_label(x)
Definition: ri.h:2450
#define basic_undefined
Definition: ri.h:556
#define expression_undefined
Definition: ri.h:1223
#define variable_dimensions(x)
Definition: ri.h:3122
#define statement_instruction(x)
Definition: ri.h:2458
#define instruction_call(x)
Definition: ri.h:1529
#define call_arguments(x)
Definition: ri.h:711
#define statement_undefined_p(x)
Definition: ri.h:2420
#define entity_type(x)
Definition: ri.h:2792
#define call_undefined
Definition: ri.h:685
#define type_variable_p(x)
Definition: ri.h:2947
#define variable_basic(x)
Definition: ri.h:3120
#define statement_undefined
Definition: ri.h:2419
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
char * strdup()
s1
Definition: set.c:247
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
bool freeze_variables(char *)
freeze_variables.c
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207