PIPS
eval.c
Go to the documentation of this file.
1 /*
2 
3  $Id: eval.c 23065 2016-03-02 09:05:50Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6  Copyright 2009-2010 HPC Project
7 
8  This file is part of PIPS.
9 
10  PIPS is free software: you can redistribute it and/or modify it
11  under the terms of the GNU General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  any later version.
14 
15  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
16  WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  FITNESS FOR A PARTICULAR PURPOSE.
18 
19  See the GNU General Public License for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
23 
24 */
25 #ifdef HAVE_CONFIG_H
26  #include "pips_config.h"
27 #endif
28 
29 #include <stdio.h>
30 #include <string.h>
31 #include <stdlib.h>
32 
33 #include "genC.h"
34 #include "linear.h"
35 #include "ri.h"
36 #include "effects.h"
37 #include "ri-util.h"
38 #include "prettyprint.h"
39 #include "effects-util.h"
40 #include "misc.h"
41 #include "text-util.h"
42 #include "newgen_set.h"
43 #include "points_to_private.h"
44 #include "pointer_values.h"
45 
46 #include "effects-generic.h"
47 #include "effects-convex.h"
48 
49 /*
50  @param r1 and r2 are two path references
51  @param strict_p is true if the path length of r1 must be strictly inferior
52  to the path length of r2
53  @param exact_p is a pointer towards a boolean, which is set to false
54  is the result is an over-approximation, true if it's an exact answer.
55  @return true if r1 path may be a predecessor of r2 path
56 
57  (we consider that p[1] is a predecessor of p[*], with *exact_p = false.)
58 
59  Note FI: the notion of predecessor is similar to having a prefix
60  subscript list. You might want an inclusion between the memory cells
61  accessed by the two references, but it is not the case since p[1] is
62  a predecessor of p[*]. And, the descriptors are used... with no
63  explanations. I guess you want to be able to say something with
64  p[i], 0<=i<=2, since p[0], p[1], p[2] and p[*] may be used.
65 
66  */
68  reference r2, descriptor d2,
70  bool strict_p,
71  bool * exact_p)
72 {
73  bool res = true;
74  entity e1 = reference_variable(r1);
75  list ind1 = reference_indices(r1);
76  size_t r1_path_length = gen_length(ind1);
77  entity e2 = reference_variable(r2);
78  list ind2 = reference_indices(r2);
79  size_t r2_path_length = gen_length(ind2);
80 
81  pips_debug(8, "input references r1 : %s, r2: %s \n",
84 
85  *exact_p = true;
86  if (same_entity_p(e1, e2)
87  && ((r1_path_length < r2_path_length)
88  || (!strict_p && r1_path_length == r2_path_length)))
89  {
90  /* same entity and the path length of r1 is shorter than the
91  * path length of r2.
92  *
93  * we now have to check that each common index matches
94  */
95  pips_debug(8,"same entities, and r1 path is shorter than r2 path\n");
96  while (res && !ENDP(ind1))
97  {
98  expression exp1 = EXPRESSION(CAR(ind1));
99  expression exp2 = EXPRESSION(CAR(ind2));
100 
101  if(!expression_equal_p(exp1, exp2))
102  {
103  res = false;
104  *exact_p = true;
105  }
106 
107  POP(ind1);
108  POP(ind2);
109  }
110  if (res)
111  {
112  /* only matching reference indices have been found (phi
113  * variables or struct field entities).
114  *
115  * we must now check the descriptors.
116  */
123 
124  pips_debug_effect(6, "reg1 = \n", reg1);
125  pips_debug_effect(6, "reg2 = \n", reg1);
126 
127  list li = region_intersection(reg1, reg2);
128  if (ENDP(li))
129  {
130  res = false;
131  *exact_p = true;
132  }
133  else
134  {
135 
136  pips_debug_effect(8, "reg2 before eliminating phi variables: \n ", reg2);
137 
138  effect reg2_dup = copy_effect(reg2);
139  list l_reg2 = CONS(EFFECT,reg2_dup,NIL);
140  list l_phi = phi_entities_list(r1_path_length+1,r2_path_length);
141  project_regions_along_variables(l_reg2, l_phi);
142  gen_free_list(l_reg2);
143  gen_free_list(l_phi);
144  pips_debug_effect(8, "reg2_dup after elimination: \n ", reg2_dup);
145 
146  effect reg1_dup = copy_effect(reg1);
148  {
150  region_sc_append(reg1_dup, sc_context, false);
151  }
152 
153  pips_debug_effect(8, "reg1_dup after adding preconditions: \n ", reg1_dup);
154  pips_debug_effect(8, "reg1 after adding preconditions: \n ", reg1);
155 
156  list ld = region_sup_difference(reg1_dup, reg2_dup);
157  if (ENDP(ld))
158  {
159  res = true;
160  *exact_p = true;
161  }
162  else
163  {
164  res = true;
165  *exact_p = false;
166  }
167  gen_full_free_list(ld);
168  }
169  gen_full_free_list(li);
170 
173  free_effect(reg1);
174 
177  free_effect(reg2);
178  }
179  }
180  else
181  {
182  res = false;
183  *exact_p = true;
184  }
185 
186  pips_debug(8, "end : r1 is %s a predecessor of r2 (%s exact)\n", res ? "":"not", *exact_p ? "":"not");
187  return res;
188 }
189 
190 
192  cell c2, descriptor d2,
194  bool strict_p,
195  bool * exact_p)
196 {
197  reference r1 = cell_any_reference(c1);
198  reference r2 = cell_any_reference(c2);
199 
201  strict_p, exact_p);
202 }
203 
204 
206 {
207 
212 
214  {
217  {
220  }
221  else
223  }
224  *output_ref = effect_any_reference(reg);
225  *output_desc = effect_descriptor(reg);
226 
227  pips_debug_effect(6, "reg = \n", reg);
228 
231  free_effect(reg);
232 }
233 
234 void simple_cell_to_convex_cell_conversion(cell input_cell, cell * output_cell, descriptor * output_desc)
235 {
236 
237  reference input_ref = cell_any_reference(input_cell);
238  reference output_ref = reference_undefined;
239 
240  simple_reference_to_convex_reference_conversion(input_ref, &output_ref, output_desc);
241  *output_cell = make_cell_reference(output_ref);
242 }
243 
244 
245 
246 
247 /*
248  @param c is a the convex cell for which we look an equivalent constant path
249  @param ptl is the list of points-to in which we search for constant paths
250  @param exact_p is a pointer towards a boolean. It is set to true if
251  the result is exact, and to false if it is an approximation,
252  either because the matching points-to sources found in ptl are
253  over-approximations of the preceding path of input_ref or because
254  the matching points-to have MAY approximation tag.
255  @return a list of constant path effects. It is a list because at a given
256  program point the cell may correspond to several constant paths.
257 
258 
259  original comment:
260  goal: see if cell c can be shortened by replacing its indirections
261  by their values when they are defined in ptl. For instance, p[0][0]
262  and (p,q,EXACT) is reduced to q[0]. And if (q,i,EXACT) is also
263  available, the reference is reduced to i. The reduced cell is less likely
264  to be invalidated by a write effect. The function is called "eval"
265  because its goal is to build an as constant as possible reference or
266  gap.
267 
268  I currently assume that points-to sinks are constant paths because
269  in the last example we should also have (p[0], i, EXACT) in the
270  points-to list. (BC)
271 
272  This function is called by effects to see if a convex memory access path
273  can be transformed into a constant one.
274 */
276 {
277 
278  return generic_eval_cell_with_points_to(c, d, ptl, exact_p, current_precondition,
282 }
283 
284 
286 {
287  list le = NIL;
288  bool exact_p;
290 
291  if (effect_reference_dereferencing_p(ref, &exact_p))
292  {
293  pips_debug(8, "dereferencing case \n");
294  bool exact_p = false;
298  else {
300  }
301 
304  &exact_p, context);
305  if (ENDP(l_eval))
306  {
307  pips_debug(8, "no equivalent constant path found -> anywhere effect\n");
308  /* We have not found any equivalent constant path : it may point anywhere */
309  /* We should maybe contract these effects later. Is it done by the callers ? */
311  }
312  else
313  {
314  /* change the resulting effects action to the current effect action */
315  if (effect_read_p(eff))
316  effects_to_read_effects(l_eval);
317  le = gen_nconc(l_eval,le);
318  }
319  }
320  else
321  le = CONS(EFFECT, copy_effect(eff), le);
322  return le;
323 }
324 
325 
327 {
328  bool exact_p;
329  list l_pv = cell_relations_list( load_pv(s));
338 
339  reset_pv_context(&ctxt);
340  return l_aliased;
341 }
342 
343 
344 
345 
347 {
348  list le = NIL;
349  bool exact_p;
351 
352  if (effect_reference_dereferencing_p(ref, &exact_p))
353  {
354  pips_debug(8, "dereferencing case \n");
355  bool exact_p = false;
357  pips_debug_effects(8, "aliased effects\n", l_aliased);
358 
359  FOREACH(EFFECT, eff_alias, l_aliased)
360  {
361  entity ent_alias = effect_entity(eff_alias);
362  if (undefined_pointer_value_entity_p(ent_alias)
363  || null_pointer_value_entity_p(ent_alias))
364  {
365  // currently interpret them as anywhere effects since these values
366  // are not yet well integrated in abstract locations lattice
367  // and in effects computations
368  // to be FIXED later.
369  le = CONS(EFFECT, make_anywhere_effect(copy_action(effect_action(eff_alias))), le);
370  free_effect(eff_alias);
371  }
372  else if (entity_abstract_location_p(effect_entity(eff_alias))
373  || !effect_reference_dereferencing_p(effect_any_reference(eff_alias), &exact_p)) {
374  le = CONS(EFFECT, eff_alias, le);
375  /* it should be a union here.
376  * However, we expect the caller
377  * to perform the contraction afterwards. */
378  }
379  else
380  free_effect(eff_alias);
381  }
382  gen_free_list(l_aliased);
383  }
384  else {
385  // functions that can be pointed by effect_dup_func:
386  // simple_effect_dup
387  // region_dup
388  // copy_effect
389  le = CONS(EFFECT, (*effect_dup_func)(eff), le);
390  }
391 
392  return le;
393 }
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
void free_effect(effect p)
Definition: effects.c:451
descriptor make_descriptor_convex(Psysteme _field_)
Definition: effects.c:439
cell make_cell(enum cell_utype tag, void *val)
Definition: effects.c:290
approximation make_approximation_exact(void)
Definition: effects.c:185
effect make_effect(cell a1, action a2, approximation a3, descriptor a4)
Definition: effects.c:484
effect copy_effect(effect p)
EFFECT.
Definition: effects.c:448
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
bool entity_abstract_location_p(entity al)
#define region
simulation of the type region
list region_sup_difference(region reg1, region reg2)
list region_sup_difference(effect reg1, reg2) input : two regions output : a list of regions containi...
bool convex_cells_intersection_p(cell c1, descriptor d1, cell c2, descriptor d2, bool *exact_p)
list region_intersection(region reg1, region reg2)
Intersection :
bool convex_cells_inclusion_p(cell c1, descriptor d1, cell c2, descriptor d2, bool *exact_p)
Inclusion test :
bool convex_cell_preceding_p(cell c1, descriptor d1, cell c2, descriptor d2, transformer current_precondition, bool strict_p, bool *exact_p)
Definition: eval.c:191
list convex_effect_to_constant_path_effects_with_pointer_values(effect __attribute__((unused)) eff)
Definition: eval.c:346
bool convex_cell_reference_preceding_p(reference r1, descriptor d1, reference r2, descriptor d2, transformer current_precondition, bool strict_p, bool *exact_p)
eval.c
Definition: eval.c:67
void simple_reference_to_convex_reference_conversion(reference ref, reference *output_ref, descriptor *output_desc)
Definition: eval.c:205
void simple_cell_to_convex_cell_conversion(cell input_cell, cell *output_cell, descriptor *output_desc)
Definition: eval.c:234
list convex_effect_find_aliased_paths_with_pointer_values(effect eff, statement s)
Definition: eval.c:326
list eval_convex_cell_with_points_to(cell c, descriptor d, list ptl, bool *exact_p, transformer current_precondition)
Definition: eval.c:275
list convex_effect_to_constant_path_effects_with_points_to(effect eff)
Definition: eval.c:285
void convex_cell_reference_with_address_of_cell_reference_translation(reference, descriptor, reference, descriptor, int, reference *, descriptor *, bool *)
list phi_entities_list(int, int)
void convex_cell_with_address_of_cell_translation(cell, descriptor, cell, descriptor, int, cell *, descriptor *, bool *)
void region_sc_append(effect, Psysteme, bool)
void convex_cell_with_value_of_cell_translation(cell, descriptor, cell, descriptor, int, cell *, descriptor *, bool *)
void convex_region_add_expression_dimension(effect, expression)
void project_regions_along_variables(list, list)
void project_regions_along_variables(list l_reg, list l_param) input : a list of regions to project,...
#define pips_debug_effects(level, message, l_eff)
#define pips_debug_effect(level, message, eff)
for debug
list generic_effect_find_aliases_with_simple_pointer_values(effect eff, list l_pv, bool *exact_p, transformer current_precondition, bool(*cell_preceding_p_func)(cell, descriptor, cell, descriptor, transformer, bool, bool *), void(*cell_with_address_of_cell_translation_func)(cell, descriptor, cell, descriptor, int, cell *, descriptor *, bool *), void(*cell_with_value_of_cell_translation_func)(cell, descriptor, cell, descriptor, int, cell *, descriptor *, bool *), bool(*cells_intersection_p_func)(cell, descriptor, cell, descriptor, bool *), bool(*cells_inclusion_p_func)(cell, descriptor, cell, descriptor, bool *), void(*simple_cell_conversion_func)(cell, cell *, descriptor *))
Definition: eval.c:673
list generic_eval_cell_with_points_to(cell input_cell, descriptor input_desc, list ptl, bool *exact_p, transformer current_precondition, bool(*cell_reference_preceding_p_func)(reference, descriptor, reference, descriptor, transformer, bool, bool *), void(*cell_reference_with_address_of_cell_reference_translation_func)(reference, descriptor, reference, descriptor, int, reference *, descriptor *, bool *), void(*cell_reference_conversion_func)(reference, reference *, descriptor *))
Definition: eval.c:361
bool effects_private_current_context_empty_p(void)
effect make_anywhere_effect(action)
transformer effects_private_current_context_head(void)
statement effects_private_current_stmt_head(void)
effect(* effect_dup_func)(effect eff)
void effects_to_read_effects(list)
void effect_add_field_dimension(effect, entity)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define effect_read_p(eff)
#define effect_scalar_p(eff) entity_scalar_p(effect_entity(eff))
reference cell_any_reference(cell)
API for reference.
Definition: effects.c:77
bool effect_reference_dereferencing_p(reference, bool *)
Definition: type.c:233
entity effect_entity(effect)
cproto-generated files
Definition: effects.c:52
action make_action_write_memory(void)
To ease the extension of action with action_kind.
Definition: effects.c:1011
bool undefined_pointer_value_entity_p(entity)
points_to_list load_pt_to_list(statement)
bool null_pointer_value_entity_p(entity)
#define cell_reference(x)
Definition: effects.h:469
#define cell_relations_list(x)
Definition: effects.h:549
#define effect_action(x)
Definition: effects.h:642
@ is_cell_reference
Definition: effects.h:445
#define effect_descriptor(x)
Definition: effects.h:646
#define descriptor_undefined
Definition: effects.h:559
#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
#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
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 pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
pv_context make_simple_pv_context(void)
cell_relations load_pv(statement)
void reset_pv_context(pv_context *)
#define points_to_list_list(x)
string reference_to_string(reference r)
Definition: expression.c:87
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
bool entity_field_p(entity e)
e is the field of a structure
Definition: entity.c:857
bool expression_equal_p(expression e1, expression e2)
Syntactic equality e1==e2.
Definition: expression.c:1347
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
#define transformer_undefined
Definition: ri.h:2847
#define transformer_undefined_p(x)
Definition: ri.h:2848
#define reference_undefined
Definition: ri.h:2302
#define reference_variable(x)
Definition: ri.h:2326
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define transformer_relation(x)
Definition: ri.h:2873
#define reference_indices(x)
Definition: ri.h:2328
#define predicate_system(x)
Definition: ri.h:2069
Psysteme sc_new(void)
Psysteme sc_new(): alloue un systeme vide, initialise tous les champs avec des valeurs nulles,...
Definition: sc_alloc.c:55
static transformer current_precondition
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
Definition: delay.c:253
pv_context is a structure holding the methods to use during pointer values analyses
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207