PIPS
alias_classes.c
Go to the documentation of this file.
1 /*
2 
3  $Id: alias_classes.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 
28 #include <stdio.h>
29 #include <string.h>
30 
31 #include <setjmp.h>
32 
33 #include "genC.h"
34 #include "linear.h"
35 
36 #include "ri.h"
37 #include "effects.h"
38 
39 #include "ri-util.h"
40 #include "effects-util.h"
41 #include "misc.h"
42 
43 #include "effects-generic.h"
44 #include "effects-convex.h"
45 
46 #include "semantics.h"
47 #include "transformer.h"
48 
49 #include "pipsdbm.h"
50 
51 //#include "points_to_private.h"
52 #include "alias-classes.h"
53 
56 
57 
58 /* tests if reg1 and reg2 are the same,
59  * ignoring their action_tags (IN/OUT)
60  * but checking their precision (may/exact)
61  */
62 static bool
64  {
65  Psysteme reg1_sys, reg2_sys;
66  bool result = false;
67 
68  pips_debug(4,"begin\n");
69 
70  if (effect_undefined_p(reg1) || effect_undefined_p(reg2)) return result;
71 
72  if (effect_entity(reg1) == effect_entity(reg2))
73  {
74 /* pips_debug(1,"same entity\n"); */
75 
76  if (effect_approximation_tag(reg1) ==
78  {
79 /* pips_debug(1,"same approx\n"); */
80 
81  ifdebug(1)
82  {
84  pips_debug(1,"compare:\n\t");
85  print_region(reg1);
86  pips_debug(1,"with:\n\t");
87  print_region(reg2);
89  }
90 
91  reg1_sys = region_system(reg1);
92  reg2_sys = region_system(reg2);
93  if ( sc_equal_p_ofl(reg1_sys,reg2_sys) )
94  {
95  result = true;
96 
97  pips_debug(1,"same region\n");
98  }
99  else
100  pips_debug(1,"not same region\n");
101  }
102  }
103  pips_debug(4,"end\n");
104 
105  return result;
106  }
107 
108 
109 /* tests if reg and any member of reg_list
110  * are same_reg_ignore_action
111  */
112 static bool
113 member(region reg, list reg_list)
114  {
115  region elem;
116  list rest_list;
117  bool result = false;
118 
119  pips_debug(4,"begin\n");
120 
121 /*
122  ifdebug(9)
123  {
124  set_action_interpretation(ACTION_IN,ACTION_OUT);
125  pips_debug(9,"test if:\n\t");
126  print_region(reg);
127  pips_debug(9,"is in:\n\t");
128  print_inout_regions(reg_list);
129  reset_action_interpretation();
130  }
131  */
132 
133  rest_list = reg_list;
134 
135  if (reg_list != NIL)
136 
137  do{
138  elem = EFFECT(CAR(rest_list));
139  if (same_reg_ignore_action(elem,reg))
140  {
141  result = true;
142 
143  pips_debug(4,"is member\n");
144  }
145 
147  }while (rest_list != NIL && result == false);
148 
149  pips_debug(4,"end\n");
150 
151  return result;
152  }
153 
154 
155 /* adds reg as final element on the end of reg_list
156  * unless reg is already present in reg_list
157  * i.e. is same_reg_ignore_action as an element of reg_list
158  */
159 static list
161 {
162  list new_reg_list;
163 
164  pips_debug(4,"begin\n");
165 
166 
167 /*
168  ifdebug(9)
169  {
170  set_action_interpretation(ACTION_IN,ACTION_OUT);
171  pips_debug(9,"add:\n\t");
172  print_region(reg);
173  pips_debug(9,"to:\n\t");
174  print_inout_regions(reg_list);
175  reset_action_interpretation();
176  }
177 */
178 
179  if (!member(reg,reg_list))
180  new_reg_list = gen_nconc(reg_list,CONS(EFFECT,reg,NIL));
181  else
182  new_reg_list = reg_list;
183 
184  pips_debug(4,"end\n");
185 
186  return new_reg_list;
187 }
188 
189 
190 /* add a copy of each element in additional_list
191  * not already present in initial_reg_list
192  * to the end of initial_reg_list
193  * (ignoring the action)
194  */
195 static list
196 union_lists(list initial_reg_list, list additional_list)
197 {
198  list new_reg_list = initial_reg_list;
199 
200  pips_debug(4,"begin\n");
201 
202  MAP(EFFECT,additional_reg,
203  {
204  new_reg_list =
205  append_reg_if_not_present(new_reg_list,additional_reg);
206  },additional_list);
207 
208  pips_debug(4,"end\n");
209 
210  return new_reg_list;
211 }
212 
213 
214 /* global variables IN: rest_list, l_lists
215  * global variables modified: rest_list, l_lists
216  */
217 static void
218 compare_other_list(region elem, list other_list)
219 {
220  bool result = false;
221  region other_elem;
222  list rest_other_list;
223 
224  ifdebug(4)
225  {
226  pips_debug(4,"begin for elem:\n");
228  print_region(elem);
230  pips_debug(4,"and list:\n");
231  print_inout_regions(other_list);
232  }
233 
234  if (other_list != NIL)
235  {
236  rest_other_list = other_list;
237  do {
238  other_elem = EFFECT(CAR(rest_other_list));
239  rest_other_list = CDR(rest_other_list);
240 
241  ifdebug(9)
242  {
243  pips_debug(9,"compare elem:\n");
245  print_region(other_elem);
247  }
248 
249  if ( effect_exact_p(other_elem) )
250  {
251  pips_debug(9,"exact\n");
252 
253 /* here, it doesn't matter whether the regions have the same action */
254  if ( same_reg_ignore_action(elem,other_elem) )
255  {
256  pips_debug(9,"same\n");
257 
258  rest_list = union_lists(rest_list,other_list);
259  result = true;
260  }
261  }
262  } while (result == false && rest_other_list != NIL);
263  if (result == false)
264  l_lists = CONS(LIST,other_list,l_lists);
265  }
266  pips_debug(4,"end\n");
267 }
268 
269 
270 /* global variables IN: rest_list, rest_lists, l_lists
271  * global variables modified: rest_list, l_lists, rest_lists
272  * compares "elem" (the current element from
273  * the list currently being made into a class)
274  * to each element of each list of "rest_lists"
275  * (the other lists not yet made into classes)
276  * if a match is found, "other_list"
277  * (the other list containing the matching element "other_elem")
278  * is appended to "rest_list" (the not yet treated elements from the list
279  * currently being made into a class)
280  * and "other_list" will no longer be a member of "l_lists"
281  * if not, "other_list" is appended to "l_lists"
282  */
283 static void
285 {
286  list other_list;
287 
288  while (rest_lists != NIL)
289  {
290  ifdebug(4)
291  {
292  pips_debug(4,"begin for:\n");
294  print_region(elem);
296  }
297 
298  other_list = LIST(CAR(rest_lists));
300  compare_other_list(elem, other_list);
301  }
302  pips_debug(4,"end\n");
303 }
304 
305 
306 /* global variables IN: new_class, rest_lists, l_lists
307  * global variables modified: new_class, l_lists, rest_lists, rest_list
308  */
309 static void
311 {
312  region elem;
313 
314  ifdebug(4)
315  {
316  pips_debug(4,"begin for:\n");
317  print_inout_regions(reg_list);
318  }
319 
320  rest_list = reg_list;
321 
322  while (rest_list != NIL)
323  {
324  elem = EFFECT(CAR(rest_list));
326 
327  ifdebug(9)
328  {
329  pips_debug(9,"elem:\n");
331  print_region(elem);
333  }
334 
335  if ( effect_exact_p(elem) )
336  {
337  pips_debug(9,"exact\n");
338 
340  l_lists = NIL;
341  compare_rest_lists(elem);
342  }
344  }
345 
346  pips_debug(4,"end\n");
347 }
348 
349 
350 /* global variables IN: l_lists, l_alias_classes
351  * global variables modified:class, l_lists, rest_lists, rest_list,
352  * l_alias_classes
353  */
354 static void
356 {
357  list next_list;
358 
359  while (l_lists != NIL)
360  {
361  pips_debug(4,"begin\n");
362 
363  next_list = LIST(CAR(l_lists));
364  l_lists = CDR(l_lists);
365  new_class = NIL;
366 
367  make_class_from_list(next_list);
371 
372 /* ifdebug(9)
373  {
374  pips_debug(9,"new_class:\n");
375  print_inout_regions(new_class);
376  pips_debug(9,"l_lists:\n");
377  MAP(LIST,alias_list,
378  {
379  print_inout_regions(alias_list);
380  pips_debug(9,"---\n");
381  },
382  l_lists);
383  }*/
384 
385 /* if (l_lists != NIL) unite_lists_containing_same_exact_region(); */
386  }
387  pips_debug(4,"end\n");
388 }
389 
390 
391 /* global variables IN: l_alias_lists
392  * global variables modified: l_alias_lists
393  * compares "head" (the head of the current list)
394  * to the head of each list of "rest_lists"
395  * (the other lists not yet treated)
396  * if a match is found, "other_list"
397  * (the other list containing the matching head "other_head")
398  * is appended to "new_list"
399  * and "other_list" will no longer be a member of "l_alias_lists"
400  * if not, "other_list" is appended to "l_alias_lists"
401  */
402 static list
404 {
406  region other_head;
407 
409  l_alias_lists = NIL;
410 
411  MAP(LIST, other_list,
412  {
413  ifdebug(4)
414  {
415  pips_debug(4,"begin for:\n");
417  print_region(head);
419  }
420 
421  if (other_list != NIL)
422  {
423  other_head = EFFECT(CAR(other_list));
424 
425  ifdebug(9)
426  {
427  pips_debug(9,"compare elem:\n");
429  print_region(other_head);
431  }
432 
433 /* here, we don't need to account of the actions of the
434  * two regions: if a sub-program has the same IN and
435  * OUT regions for one array, then we will have
436  * created two alias lists which are identical except for
437  * the actions of the regions: now we get rid of one
438  */
439  if ( same_reg_ignore_action(head,other_head) )
440  {
441  pips_debug(9,"same\n");
442 
443  new_list = union_lists(new_list,CDR(other_list));
444  }
445  else
446  {
447  l_alias_lists = CONS(LIST,other_list,l_alias_lists);
448  }
449  }
450 
451  },rest_lists);
452 
453  pips_debug(4,"end\n");
454 
455  return new_list;
456 }
457 
458 
459 /* global variables IN: l_alias_lists, l_lists
460  * global variables modified: l_alias_lists, l_lists
461  */
462 static void
464 {
465  list next_list, new_list;
466  region head;
467 
468  pips_debug(4,"begin\n");
469 
470  while (l_alias_lists != NIL)
471  {
472 
473  next_list = LIST(CAR(l_alias_lists));
475  new_list = next_list;
476 
477  if (next_list != NIL)
478  {
479  head = EFFECT(CAR(next_list));
480 
481  ifdebug(9)
482  {
483  pips_debug(9,"head:\n");
485  print_region(head);
487  }
488 
489  new_list = compare_heads_rest_lists(head, new_list);
490  }
491 
492  l_lists = CONS(LIST,new_list,l_lists);
493 
494 /* ifdebug(9)
495  {
496  pips_debug(9,"new_list:\n");
497  print_inout_regions(new_list);
498  pips_debug(9,"l_alias_lists:\n");
499  MAP(LIST,alias_list,
500  {
501  print_inout_regions(alias_list);
502  pips_debug(9,"---\n");
503  },
504  l_alias_lists);
505  }
506  */
507  }
508 
509  pips_debug(4,"end\n");
510 }
511 
512 
513 bool
515 {
516  entity module;
517  list module_alias_lists;
518 
519  debug_on("ALIAS_CLASSES_DEBUG_LEVEL");
520  pips_debug(4,"begin for module %s\n",module_name);
521  ifdebug(4)
522  {
523  /* ATTENTION: we have to do ALL this
524  * just to call print_inout_regions for debug !!
525  */
530  db_get_memory_resource(DBR_CODE,
531  module_name,
532  true) );
535  DBR_CUMULATED_EFFECTS,
536  module_name,
537  true));
540  DBR_PROPER_EFFECTS,
541  module_name,
542  true));
544  /* and this to call print_region
545  set_action_interpretation(ACTION_IN,ACTION_OUT); */
546  /* that's it, but we musn't forget to reset everything below */
547  }
548 
549  l_alias_lists = NIL;
551  l_lists = NIL;
552 
553  module_alias_lists =
555  db_get_memory_resource(DBR_ALIAS_LISTS,
556  module_name,
557  true));
558  MAP(EFFECTS,module_alias_list_effects,
559  {
560  list module_alias_list =
561  effects_effects(module_alias_list_effects);
562 
563 /* ifdebug(9)
564  {
565  pips_debug(9,"add list:\n");
566  print_inout_regions(module_alias_list);
567  }
568  */
569  l_alias_lists = CONS(LIST,module_alias_list,l_alias_lists);
570  },module_alias_lists);
571 
572  ifdebug(9)
573  {
574  pips_debug(9,"alias lists:\n");
575  MAP(LIST,alias_list,
576  {
577  print_inout_regions(alias_list);
578  pips_debug(9,"---\n");
579  },
580  l_alias_lists);
581  }
582 
584 
585  ifdebug(9)
586  {
587  pips_debug(9,"new lists:\n");
588  MAP(LIST,alias_list,
589  {
590  print_inout_regions(alias_list);
591  pips_debug(9,"---\n");
592  },
593  l_lists);
594  }
595 
597 
598  ifdebug(9)
599  {
600  pips_debug(9,"classes:\n");
601  MAP(EFFECTS,alias_class,
602  {
603  print_inout_regions(effects_effects(alias_class));
604  },
606  }
607 
608  DB_PUT_MEMORY_RESOURCE(DBR_ALIAS_CLASSES,
611 
612  ifdebug(4)
613  {
619  }
620  pips_debug(4,"end\n");
621  debug_off();
622 
623  return true;
624 }
625 
effects_classes make_effects_classes(list a)
Definition: effects.c:526
effects make_effects(list a)
Definition: effects.c:568
static list compare_heads_rest_lists(region head, list new_list)
global variables IN: l_alias_lists global variables modified: l_alias_lists compares "head" (the head...
static bool member(region reg, list reg_list)
tests if reg and any member of reg_list are same_reg_ignore_action
static list append_reg_if_not_present(list reg_list, region reg)
adds reg as final element on the end of reg_list unless reg is already present in reg_list i....
static list rest_lists
Definition: alias_classes.c:55
static void make_class_from_list(list reg_list)
global variables IN: new_class, rest_lists, l_lists global variables modified: new_class,...
static bool same_reg_ignore_action(region reg1, region reg2)
tests if reg1 and reg2 are the same, ignoring their action_tags (IN/OUT) but checking their precision...
Definition: alias_classes.c:63
static list l_alias_lists
Definition: alias_classes.c:54
bool alias_classes(const char *module_name)
alias_classes.c
static void unite_lists_containing_same_exact_region()
global variables IN: l_lists, l_alias_classes global variables modified:class, l_lists,...
static void unite_lists_with_same_head()
global variables IN: l_alias_lists, l_lists global variables modified: l_alias_lists,...
static list new_class
Definition: alias_classes.c:55
static list rest_list
Definition: alias_classes.c:55
static void compare_rest_lists(region elem)
global variables IN: rest_list, rest_lists, l_lists global variables modified: rest_list,...
static list l_alias_classes
Definition: alias_classes.c:54
static void compare_other_list(region elem, list other_list)
global variables IN: rest_list, l_lists global variables modified: rest_list, l_lists
static list union_lists(list initial_reg_list, list additional_list)
add a copy of each element in additional_list not already present in initial_reg_list to the end of i...
static list l_lists
Definition: alias_classes.c:55
#define region_system(reg)
#define region
simulation of the type region
list regions_dup(list)
void print_inout_regions(list)
#define ACTION_IN
#define ACTION_OUT
void reset_action_interpretation(void)
void reset_proper_rw_effects(void)
void set_proper_rw_effects(statement_effects)
void set_cumulated_rw_effects(statement_effects)
void set_action_interpretation(string, string)
prettyprint.c
void reset_cumulated_rw_effects(void)
#define effect_approximation_tag(eff)
#define effect_exact_p(eff)
entity effect_entity(effect)
cproto-generated files
Definition: effects.c:52
#define effect_undefined_p(x)
Definition: effects.h:615
#define EFFECTS(x)
EFFECTS.
Definition: effects.h:682
#define effects_effects(x)
Definition: effects.h:710
#define effects_classes_classes(x)
Definition: effects.h:678
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
#define LIST(x)
Definition: genC.h:93
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
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
#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
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#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
#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 debug_off()
Definition: misc-local.h:160
static char * module
Definition: pips.c:74
#define print_region(x)
Definition: print.c:343
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
char * strdup()
void module_to_value_mappings(entity m)
void module_to_value_mappings(entity m): build hash tables between variables and values (old,...
Definition: mappings.c:624
#define ifdebug(n)
Definition: sg.c:47
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
void free_value_mappings(void)
Normal call to free the mappings.
Definition: value.c:1212
#define sc_equal_p_ofl(ps1, ps2)
Definition: union-local.h:84