PIPS
variable.c
Go to the documentation of this file.
1 /*
2 
3  $Id: variable.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 /*
26  * This file contains functions used to compute all pointer locations
27  * within an entity, if any. It is tricky for structures containing
28  * structures and for arrays of structures or pointeurs and much
29  * easier for scalar pointers.
30  *
31  * Several pieces of code have been cut-and-pasted. Either more
32  * functions should have been defined or array of structs are not
33  * handled in a graceful way or both problems occur.
34  *
35  * The similar functions in Amira's implementation are located in
36  * points_to_analysis_general_algorithm.c.
37  */
38 
39 #include <stdlib.h>
40 #include <stdio.h>
41 #include "genC.h"
42 #include "linear.h"
43 #include "ri.h"
44 #include "effects.h"
45 #include "database.h"
46 #include "ri-util.h"
47 #include "effects-util.h"
48 #include "constants.h"
49 #include "misc.h"
50 #include "properties.h"
51 #include "effects-generic.h"
52 #include "effects-simple.h"
53 //#include "effects-convex.h"
54 #include "newgen_set.h"
55 #include "points_to_private.h"
56 #include "points-to.h"
57 
58 ␌
59 /* When the declaration of "e" does not contain an initial value, find
60  * all allocated pointers in entity e. We distinguish between scalar
61  * pointers, array of pointers and struct containing pointers and
62  * struct. Return a list of cells each containing a reference to aa
63  * pointer. These cells are used later as sources to build a points-to
64  * data structure pointing to nowhere/undefined.
65  */
67 {
68  list l = NIL;
69 
70  if (entity_variable_p(e)) {
71  /*AM: missing recursive descent on variable_dimensions. int a[*(q=p)]*/
72 
75  if (entity_array_p(e)) {
76  /* variable v = type_variable(t); */
77  /* int d = (int) gen_length(variable_dimensions(v)); */
78  /* list sl = NIL; */
79  /* int i; */
80  /* for(i=0;i<d;i++) { */
81  /* expression ind = make_unbounded_expression(); */
82  /* sl = CONS(EXPRESSION, ind, sl); */
83  /* } */
84  /* reference r = make_reference(e, sl); */
88  l = CONS(CELL, c, NIL);
89  }
90  else {
91  // FI: could be unified with previous case using d==0
94  l = CONS(CELL, c, NIL);
95  }
96  }
97  else if(struct_type_p(t) || array_of_struct_type_p(t)) {
99  entity ee = basic_derived(b);
101  }
102  //free_type(t); ee is used above
103  }
104 
105  return l;
106 }
107 
108 /* return list of cells for pointers declared directly or indirecltly in
109  * variable "e" of type struct defined by entity "ee" and its type.
110  *
111  * Typedefs have already been taken care of by the caller (?).
112  *
113  * Signature with e and ee inherited from Amira Mensi.
114  */
116 {
117  list l = NIL;
118  // bool eval = true;
119  type tt = entity_type(ee);
120  pips_assert("entity ee has type struct", type_struct_p(tt));
121  list fl = type_struct(tt); // list of fields, or field list
122 
123  list sl = NIL;
124  if(array_entity_p(e)) {
125  int i;
126  for(i=0; i< variable_entity_dimension(e); i++) {
128  sl = CONS(EXPRESSION, se, sl);
129  }
130  }
131 
132  FOREACH(ENTITY, f, fl) {
135  // FI: I wonder if we should not build the points-to right away
136  // when we know the type of the nowehere/undefined cell;
137  // reminder: this type is useful to switch to a anywhere
138  // abstract location
139  list l2 = NIL;
140  if(array_type_p(entity_type(f))) {
142  l2 = CONS(EXPRESSION, s2, NIL);
143  }
145  list fsl = CONS(EXPRESSION, s, l2); // field list
146  list nsl = gen_full_copy_list(sl); // subscript list
147  list fl = gen_nconc(nsl,fsl); // full list
148  reference r = make_reference(e, fl);
149  cell c = make_cell_reference(r);
150  l = gen_nconc(l, CONS(CELL, c, NIL));
151  }
152  else if(struct_type_p(ft) || array_of_struct_type_p(ft)) {
153  // The main data structure contains a secondary data structure
154  // FI: build the prefix and go down
155  list l2 = NIL;
156  if(array_type_p(entity_type(f))) {
158  l2 = CONS(EXPRESSION, s2, gen_full_copy_list(l2));
159  }
161  list fsl = CONS(EXPRESSION, s, l2); // field list
162  list nsl = gen_full_copy_list(sl); // subscript list
163  list fl = gen_nconc(nsl,fsl); // full list
164  reference r = make_reference(e, fl);
165  cell c = make_cell_reference(r);
166 
167  /* Find pointers downwards and build a list of cells. */
169 
170  free_cell(c);
171  l = gen_nconc(l, ll);
172  //pips_internal_error("Not implemented yet.\n");
173  //l = array_of_struct_to_pointer_location(e, ee);
174  }
175  }
176  gen_full_free_list(sl);
177  return l;
178 }
179 
180 /* returns a list of cells to reach pointers depending
181  * on field f. Cell c is the current prefix.
182  */
184 {
185  list sl = NIL;
187  pips_assert("We are dealing with a struct", struct_type_p(ft)
188  || array_of_struct_type_p(ft));
190  type st = entity_type(basic_derived(fb));
191  list sfl = type_struct(st);
192 
193  /* In case we are dealing with an array of structs, add subscript
194  expressions in mc, a modified copy of parameter c */
195  cell mc = copy_cell(c); // modified cell c
196  /*
197  if(array_type_p(ft)) {
198  list ssl = NIL;
199  int i;
200  for(i=0; i< variable_dimension_number(type_variable(ft)); i++) {
201  expression se = make_unbounded_expression();
202  ssl = CONS(EXPRESSION, se, ssl);
203  }
204  reference r = cell_any_reference(mc);
205  reference_indices(r) = gen_nconc(reference_indices(r), ssl);
206  }
207  */
208 
209  /* Take care of each field in the structure. */
210  FOREACH(ENTITY, sf, sfl) {
211  type sft = ultimate_type(entity_type(sf));
212  if(pointer_type_p(sft) || array_of_pointers_type_p(sft)) {
213  /* copy cell c and add a subscript for f */
214  cell nc = copy_cell(mc);
218  CONS(EXPRESSION, se, NIL));
219  if(array_entity_p(sf)) {
222  CONS(EXPRESSION, ue, NIL));
223  }
224  sl = gen_nconc(sl, CONS(CELL, nc, NIL));
225  }
226  else if(struct_type_p(sft) || array_of_struct_type_p(sft)) {
227  /* copy cell c and add a subscript for f */
228  cell nc = copy_cell(c);
232  CONS(EXPRESSION, se, NIL));
233  if(array_entity_p(sf)) {
236  CONS(EXPRESSION, ue, NIL));
237  }
239  sl = gen_nconc(sl, nsl);
240  free_cell(nc);
241  }
242  }
243 
244  free_cell(mc);
245 
246  return sl;
247 }
cell make_cell_reference(reference _field_)
Definition: effects.c:293
void free_cell(cell p)
Definition: effects.c:249
cell copy_cell(cell p)
CELL.
Definition: effects.c:246
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
reference cell_any_reference(cell)
API for reference.
Definition: effects.c:77
void points_to_cell_add_unbounded_subscripts(cell)
Definition: effects.c:1632
#define CELL(x)
CELL.
Definition: effects.h:424
void gen_full_free_list(list l)
Definition: genClib.c:1023
#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 FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
list gen_full_copy_list(list l)
Copy a list structure with element copy.
Definition: list.c:535
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
list variable_to_pointer_locations(entity e)
When the declaration of "e" does not contain an initial value, find all allocated pointers in entity ...
Definition: variable.c:66
list struct_variable_to_pointer_subscripts(cell c, entity f)
returns a list of cells to reach pointers depending on field f.
Definition: variable.c:183
list struct_variable_to_pointer_locations(entity e, entity ee)
return list of cells for pointers declared directly or indirecltly in variable "e" of type struct def...
Definition: variable.c:115
int variable_entity_dimension(entity v)
variable_entity_dimension(entity v): returns the dimension of variable v; scalar have dimension 0.
Definition: variable.c:1293
#define entity_variable_p(e)
An entity_variable_p(e) may hide a typedef and hence a functional type.
bool entity_array_p(entity e)
Is e a variable with an array type?
Definition: entity.c:754
bool array_entity_p(entity e)
Definition: entity.c:793
expression make_unbounded_expression()
Definition: expression.c:4339
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
type ultimate_type(type)
Definition: type.c:3466
bool array_type_p(type)
Definition: type.c:2942
bool array_of_pointers_type_p(type)
Definition: type.c:3025
type entity_basic_concrete_type(entity)
retrieves or computes and then returns the basic concrete type of an entity
Definition: type.c:3677
bool pointer_type_p(type)
Check for scalar pointers.
Definition: type.c:2993
bool struct_type_p(type)
Returns true if t is of type derived and if the derived type is a struct.
Definition: type.c:3121
bool array_of_struct_type_p(type)
Definition: type.c:3133
#define type_struct(x)
Definition: ri.h:2964
#define type_struct_p(x)
Definition: ri.h:2962
#define basic_derived(x)
Definition: ri.h:640
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define type_variable(x)
Definition: ri.h:2949
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define reference_indices(x)
Definition: ri.h:2328
#define entity_type(x)
Definition: ri.h:2792
#define variable_basic(x)
Definition: ri.h:3120
The structure used to build lists in NewGen.
Definition: newgen_list.h:41