PIPS
points_to.c
Go to the documentation of this file.
1 /*
2 
3  $Id$
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 /* Interface with points-to library */
29 
30 #include <stdio.h>
31 #include <string.h>
32 
33 #include "genC.h"
34 #include "linear.h"
35 
36 #include "misc.h"
37 //#include "properties.h"
38 
39 #include "ri.h"
40 #include "effects.h"
41 
42 #include "ri-util.h"
43 //#include "prettyprint.h"
44 #include "effects-util.h"
45 #include "resources.h"
46 #include "pipsdbm.h"
47 
48 // For semantics_user_warning()
49 #include "transformer.h"
50 #include "semantics.h"
51 
52 //#include "text-util.h"
53 #include "effects-generic.h"
54 //#include "effects-simple.h"
55 #include "effects-convex.h"
56 
57 #include "pips-libs.h"
58 #ifdef HAVE_PIPS_points_to_LIBRARY
59 
60 #include "points-to.h"
61 
62 /*
63  * Functions relying on points-to.h
64  */
65 
66 /* Special wrapping for the effects analyses
67  *
68  * FI: check if new cells are allocated to build the returned location
69  * list ll...
70  */
72 {
74  if (!pt_to_list_undefined_p()) {
77  }
78 
80  return ll;
81 }
82 
83 /* Returns a list of cells */
85 {
86  list ll = list_undefined;
87 
88  /* Points to are not as precise as proper effects because they are
89  * based on cumulated effects. Let's try to get more precise
90  * locations when an address of operator is used.
91  */
92  if(expression_call_p(e)) {
93  call c = expression_call(e);
94  entity f = call_function(c);
95  if(ENTITY_ADDRESS_OF_P(f)) {
97  if(expression_reference_p(a)) {
99  // memory_dereferencing_p
100  bool exact_p;
101  if(!effect_reference_dereferencing_p(r, &exact_p)) {
103  ll = CONS(CELL, nc, NIL);
104  }
105  }
106  else {
107  // This function is not as precise because it deals with
108  // constant effects only
110  }
111  }
112  }
113 #if false
114  // FI: is handled at a higher level
115  // if(!get_bool_property("CONSTANT_PATH_EFFECTS")) {
116  if(!get_constant_paths_p()) {
117  if(expression_reference_p(e)) {
118  // Express the dereferencing with an additional subscript
120  reference nr = copy_reference(r);
121  reference_indices(nr) =
125  ll = CONS(CELL, nc, NIL);
126  }
127  else {
128  list pel = NIL;
130  gen_free_list(el); // It is not needed. Memory leak ?
131  }
132  }
133 #endif
134 
135  if(list_undefined_p(ll)) {
136  if(pt_to_list_undefined_p()) {
139  ll = CONS(CELL, c, NIL);
140  }
141  else {
144  ll = expression_to_points_to_sinks(e, ptg);
145  }
146  }
147  return ll;
148 }
149 
150 /* Compute the mapping between the formal context of the callee and
151  * the actual context of the caller.
152  *
153  * Formal arguments are not involved here, just the formal stubs
154  * created by the points-to analysis.
155  */
157  list real_args)
158 {
159  set binding = set_undefined;
163  bool bottom_p = points_to_graph_bottom(ptg);
164 
165  if(bottom_p) {
166  /* The callee does not return. The standard PIPS memory effects
167  due to the call still do exists as they may interfere with
168  parallelization. */
169  ; // FI: temporary way out of the problem
170  }
171  else {
172  call c = make_call(callee, real_args);
174  call_arguments(c) = NIL;
175  free_call(c);
176  }
177  }
178  return binding;
179 }
180 
182 {
183  /* The effect cannot be translated (probably) because the caller
184  has not initialized the calling context properly. See for
185  instance EffectsWithPointsTo/struct08.c: the main function
186  does not initialize p, q, r or s before calling the
187  initialization functions. */
188  /* FI: not in the points-to context, look for a way to retrieve
189  the statement number... */
191  // FI: this whole function
192  // backward_translation_of_points_to_formal_context_effect()
193  // should be in library effect_simple
194  string effect_to_string(effect);
196  // FI: the pass environment must be reset before the user error
197  // is raised or PIPS is likely to core dump later
198  // See resets in proper_effects_engine() unless there is a special
199  // function, effects_pips_user_error(), but I did not find it
200  semantics_user_warning("Exact effect \"%s\" of callee \"%s\" cannot be translated. "
201  "Check that the caller \"%s\" provides initialized "
202  "parameters.\n", effect_to_string(eff),
205  }
206  else {
207  semantics_user_warning("May effect \"%s\" of callee \"%s\" cannot be translated. "
208  "Check that the caller \"%s\" provides initialized "
209  "parameters.\n", effect_to_string(eff),
212  }
213 }
214 
215 /*
216  * Return a list of actual effects corresponding to an effect on the
217  * formal context "eff".
218  *
219  */
221 {
222  list ael = NIL; // Actual effect list
223 
225  // This may occur at least with coarse_grain_parallelization()
226  pips_user_warning("Inconsistency: points-to summary effects are used"
227  " to compute call site effects without points-to "
228  "information.\n");
230  }
231  else if(!set_undefined_p(binding)) {
232  ifdebug(8) print_points_to_set("binding", binding);
233  effect n_eff ;
235  n_eff = copy_effect(eff);
236  // Update the convex descriptor first
237  n_eff = substitute_stubs_in_convex_array_region(n_eff, true, binding);
238  }
239  else{
240  n_eff = copy_effect(eff);
241  }
242 
243  cell n_eff_c = effect_cell(n_eff);
244  points_to_graph bm_g = make_points_to_graph(false, binding);
245  list n_eff_cells = points_to_source_to_translations(n_eff_c, bm_g, true);
246 
247  // pips_assert("The effect is translated", !ENDP(n_eff_cells));
248 
249  if(ENDP(n_eff_cells)) {
250  /* Let's try again with PHI1 variable substituted by 0
251  * <update1:_a_1[PHI1].var1-W-EXACT-{PHI1==0}> must be replaced
252  * by equivalent convex effect update1:_a_1[0].var1-W-EXACT-{}
253  *
254  * Since points-to information does not use phi variables, all
255  * have to be replaced by 0 to attempt the translation. For instance:
256  *
257  * <compute1:_a_1_3__1[PHI1][PHI2]-R-EXACT-{PHI1==0, 0<=PHI2,
258  * PHI2<=99, compute1:_a_1[0][var1]==8}>
259  *
260  * Using
261  *
262  * compute1:_a_1_3__1[0][0]->update1:*HEAP*_l_12[0] (exact)
263  *
264  * where exact is doubtful when dealing with heap allocated locations.
265  */
267  n_eff_cells = points_to_source_to_translations(n_eff_c, bm_g, true);
268  }
269  if(ENDP(n_eff_cells)) {
271  action a = copy_action(effect_action(eff));
273  ael = CONS(EFFECT, d, NIL);
274  }
275  }
276 
278  free_points_to_graph(bm_g);
279 
280  FOREACH(CELL, n_c, n_eff_cells) {
281  if(!null_cell_p(n_c) && !nowhere_cell_p(n_c)) {
282  action ac = copy_action(effect_action(eff));
283  approximation ap = heap_cell_p(n_c) ?
287  effect nn_eff = make_effect(n_c, ac, ap, d);
288  if(descriptor_convex_p(d))
289  nn_eff = adapt_translation_as_convex_effect(nn_eff, eff);
290  ael = CONS(EFFECT, nn_eff, ael);
291  }
292  }
293 
294  /* FI: if n_eff_cells is not empty, empty(ael) means that the
295  * input code is wrong because a pointer has not been initialized
296  * properly...
297  *
298  * But, the translation error may occur on an may effect that is
299  * an overapproximation. So a user error is not 100 % sure and
300  * ael may be empty.
301  */
304  pips_assert("The effect is translated", !ENDP(ael));
305  }
306  else {
307  /* Incompatibility between call site and callee */
308  pips_user_error("Incompatibility between call site and callee.\n");
309  gen_free_list(ael);
310  ael = NIL;
311  }
312 
313  return ael;
314 }
315 
316 #else // no HAVE_PIPS_points_to_LIBRARY
317 
318 /*
319  * Local stubs for the functions relying on points-to.h
320 */
321 
322 // typedef set points_to_graph
323 
325  list real_args __attribue__((unused)))
326 {
327  set binding = set_undefined;
328  return binding;
329 }
330 
332  _UNUSED_ entity callee, _UNUSED_ list real_args, _UNUSED_ effect eff _UNUSED_ set binding)
333 {
334  pips_internal_error("points-to library not available");
335  return NIL;
336 }
337 
338 #endif // HAVE_PIPS_points_to_LIBRARY
339 
340 /* Returns a list of cells corresponding to the possibles values,
341  * i.e. abstract or concrete locations, denoted by lhs expression e.
342  *
343  * This should work whether the points-to library is
344  * available or not, but it is not yet the case.
345  *
346  * The prefix effects_ is used to have a local copy in the
347  * effects-generic library.
348  */
350 {
351  /* We expect here a test about points-to availability and a work
352  * around if the points-to library is not linked.
353  */
355 }
356 
357 /* Returns a list of cells corresponding to the value,i.e. abstract or
358  * concrete locations, denoted by lhs expression e.
359  *
360  * If "p" is a pointer, expression "p" has "p" as a source, and the
361  * sources of "*p" as sinks.
362  *
363  * This should work whether the points-to library is
364  * available or not, but it is not yet the case
365  *
366  * The prefix effects_ is used to have a local copy in the
367  * effects-generic library.
368  */
370 {
371  /* We expect here a test about points-to availability and a work
372  * around if the points-to library is not linked.
373  */
375 }
376 
378 {
379  // (*reference_to_effect_func)
380  list wel = NIL;
381  size_t n = gen_length(cl);
382  size_t u = 0; // number of useless cells
383  FOREACH(CELL, c, cl) {
385  if(nowhere_cell_p(c)) {
386  if(n==1 || n==1+u) {
387  // Would it be better to move on with a simple warning?
388  pips_user_error("Dereferencing of an undefined pointer.\n");
389  }
390  else {
391  ; // ignore
392  }
393  u++;
394  }
395  else if(null_cell_p(c)) {
396  if(n==1 || n==1+u)
397  pips_user_error("Dereferencing of a null pointer.\n");
398  else {
399  ; // ignore
400  }
401  u++;
402  }
403  else {
405  //descriptor d = make_descriptor_none();
406  if(cell_abstract_location_p(c)) {
407  // This may always capture heap locations, although they may
408  // sometimes be concrete
409  // approximation ap = make_approximation_may();
411  e = (*reference_to_effect_func)(r, a, false); // , ap, d);
412  }
413  else {
415  e = (*reference_to_effect_func)(r, a, false); // , ap, d);
416  if(n==1 || n==1+u) {
417  // approximation ap = make_approximation_exact();
418  // e = make_effect(c, a, ap, d);
419  ;
420  }
421  else {
422  // FI: it could be exact with n>1 if alternatives are null
423  // and undefined
424  //approximation ap = make_approximation_may();
425  // e = make_effect(c, a, ap, d);
426  ;
427  }
428  }
429  // Adjust type, which implies a may approximation
431  int msn = type_depth(t);
432  if(msn>0) {
439  }
440  entity re = reference_variable(r);
442  // FI: we hope that heap entities are not included here
443  pips_assert("Not a heap abstraction", !entity_heap_location_p(re));
446  reference_variable(r) = nre;
448  reference_indices(r) = NIL;
449  }
450  }
451  }
452  if(!effect_undefined_p(e))
453  wel = gen_nconc(wel, CONS(EFFECT, e, wel));
454  }
455 
458 
459  return wel;
460 }
461 
463 {
464  return cells_to_read_or_write_effects(cl, true);
465 }
466 
468 {
469  return cells_to_read_or_write_effects(cl, false);
470 }
float a2sf[2] __attribute__((aligned(16)))
USER generates a user error (i.e., non fatal) by printing the given MSG according to the FMT.
Definition: 3dnow.h:3
cell make_cell_reference(reference _field_)
Definition: effects.c:293
action copy_action(action p)
ACTION.
Definition: effects.c:77
approximation copy_approximation(approximation p)
APPROXIMATION.
Definition: effects.c:132
approximation make_approximation_may(void)
Definition: effects.c:179
effect make_effect(cell a1, action a2, approximation a3, descriptor a4)
Definition: effects.c:484
descriptor copy_descriptor(descriptor p)
DESCRIPTOR.
Definition: effects.c:389
effect copy_effect(effect p)
EFFECT.
Definition: effects.c:448
void free_approximation(approximation p)
Definition: effects.c:135
void free_points_to_graph(points_to_graph p)
points_to_graph make_points_to_graph(bool a1, set a2)
call make_call(entity a1, list a2)
Definition: ri.c:269
reference copy_reference(reference p)
REFERENCE.
Definition: ri.c:2047
void free_call(call p)
Definition: ri.c:236
bool entity_heap_location_p(entity b)
package abstract location.
static entity callee
Definition: alias_pairs.c:62
entity entity_typed_anywhere_locations(type t)
bool entity_typed_anywhere_locations_p(entity e)
Test if an entity is the bottom of the lattice.
bool adapt_convex_effect_cell_to_backward_translation(effect)
points_to.c
effect substitute_stubs_in_convex_array_region(effect, bool, set)
effect adapt_translation_as_convex_effect(effect, effect)
@ with_points_to
list effects_lhs_expression_to_sources(expression e)
Returns a list of cells corresponding to the possibles values, i.e.
Definition: points_to.c:349
set safe_user_call_to_points_to_interprocedural_binding_set(entity callee __attribue__((unused)), list real_args __attribue__((unused)))
Interface with points-to library.
Definition: points_to.c:324
list effects_lhs_expression_to_sinks(expression e)
Returns a list of cells corresponding to the value,i.e.
Definition: points_to.c:369
list cells_to_read_effects(list cl)
Definition: points_to.c:467
list cells_to_write_effects(list cl)
Definition: points_to.c:462
static list backward_translation_of_points_to_formal_context_effect(_UNUSED_ entity callee, _UNUSED_ list real_args, _UNUSED_ effect eff _UNUSED_ set binding)
Definition: points_to.c:331
list cells_to_read_or_write_effects(list cl, bool write_p)
Definition: points_to.c:377
list generic_proper_effects_of_complex_address_expression(expression, list *, int)
effect make_anywhere_effect(action)
void effect_backward_translation_error(entity, effect)
pointer_info_val get_pointer_info_kind(void)
list effect_to_constant_path_effects_with_no_pointer_information(effect)
void add_precondition_information_to_effects(list)
void effects_to_proper_approximation(list)
statement effects_private_current_stmt_head(void)
list effects_expression_to_points_to_sinks(expression)
bool get_constant_paths_p(void)
list effects_expression_to_points_to_sources(expression)
points_to.c
string effect_to_string(effect)
cell make_anywhere_points_to_cell(type t)
Function storing points to information attached to a statement.
Definition: points_to.c:87
type points_to_reference_to_concrete_type(reference)
Definition: type.c:685
reference cell_any_reference(cell)
API for reference.
Definition: effects.c:77
bool effect_reference_dereferencing_p(reference, bool *)
Definition: type.c:233
action make_action_write_memory(void)
To ease the extension of action with action_kind.
Definition: effects.c:1011
type points_to_cell_to_concrete_type(cell)
Definition: type.c:676
type points_to_expression_to_concrete_type(expression)
The type returned is stored in a hash-table.
Definition: type.c:617
bool nowhere_cell_p(cell)
Target of an undefined pointer.
Definition: effects.c:455
bool pt_to_list_undefined_p(void)
points_to.c
action make_action_read_memory(void)
Definition: effects.c:1017
bool cell_abstract_location_p(cell)
Definition: effects.c:273
bool null_cell_p(cell)
Definition: effects.c:466
bool heap_cell_p(cell)
Any heap cell, more or less abstract or typed.
Definition: effects.c:420
#define effect_undefined_p(x)
Definition: effects.h:615
#define approximation_exact_p(x)
Definition: effects.h:369
#define effect_action(x)
Definition: effects.h:642
#define effect_undefined
Definition: effects.h:614
#define CELL(x)
CELL.
Definition: effects.h:424
#define descriptor_convex_p(x)
Definition: effects.h:599
#define effect_descriptor(x)
Definition: effects.h:646
#define approximation_must_p(x)
Definition: effects.h:366
#define effect_approximation(x)
Definition: effects.h:644
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
#define effect_cell(x)
Definition: effects.h:640
void gen_full_free_list(list l)
Definition: genClib.c:1023
if(!(yy_init))
Definition: genread_lex.c:1029
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define list_undefined_p(c)
Return if a list is undefined.
Definition: newgen_list.h:75
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
size_t gen_length(const list l)
Definition: list.c:150
#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 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 _UNUSED_
Definition: misc-local.h:232
#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 pips_internal_error
Definition: misc-local.h:149
#define pips_user_error
Definition: misc-local.h:147
#define set_undefined
Definition: newgen_set.h:48
#define set_undefined_p(s)
Definition: newgen_set.h:49
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
void print_points_to_set(string, set)
list points_to_source_to_translations(cell, pt_map, bool)
Use "ptm" as a translation map.
#define points_to_graph_undefined
#define points_to_graph_bottom(x)
#define points_to_graph_set(x)
#define ENTITY_ADDRESS_OF_P(e)
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
list make_unbounded_subscripts(int d)
FI: this piece of code must have been duplicated somewhere else in an effect library.
Definition: expression.c:4346
bool expression_call_p(expression e)
Definition: expression.c:415
call expression_call(expression e)
Definition: expression.c:445
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
statement get_current_statement_from_statement_global_stack(void)
Definition: static.c:344
size_t type_depth(type)
Number of steps to access the lowest leave of type t without dereferencing.
Definition: type.c:4880
#define call_function(x)
Definition: ri.h:709
#define reference_variable(x)
Definition: ri.h:2326
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define reference_indices(x)
Definition: ri.h:2328
#define call_arguments(x)
Definition: ri.h:711
#define semantics_user_warning
points_to_graph get_points_to_graph_from_statement(_UNUSED_ statement st)
Interface with points-to library.
Definition: points_to.c:56
list expression_to_points_to_sinks(_UNUSED_ expression e, _UNUSED_ points_to_graph in)
Definition: points_to.c:63
set user_call_to_points_to_interprocedural_binding_set(call c, pt_map pt_caller)
Compute the binding relations in a complete interprocedural way: be as accurate as possible.
Definition: points_to.c:79
list expression_to_points_to_sources(_UNUSED_ expression e, _UNUSED_ points_to_graph in)
Definition: points_to.c:71
#define ifdebug(n)
Definition: sg.c:47
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59
The structure used to build lists in NewGen.
Definition: newgen_list.h:41