PIPS
eval.c
Go to the documentation of this file.
1 /*
2 
3  $Id: eval.c 23412 2017-08-09 15:07:09Z irigoin $
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-simple.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  */
61  reference r2, descriptor __attribute__ ((unused)) d2,
63  bool strict_p,
64  bool * exact_p)
65 {
66  bool res = true;
67  entity e1 = reference_variable(r1);
68  list ind1 = reference_indices(r1);
69  size_t r1_path_length = gen_length(ind1);
70  entity e2 = reference_variable(r2);
71  list ind2 = reference_indices(r2);
72  size_t r2_path_length = gen_length(ind2);
73 
74  pips_debug(8, "input references r1 : %s, r2: %s \n",
77 
78  *exact_p = true;
79  if (same_entity_p(e1, e2)
80  && ((r1_path_length < r2_path_length)
81  || (!strict_p && r1_path_length == r2_path_length)))
82  {
83  /* same entity and the path length of r1 is shorter than the path length of r2.
84  we now have to check that each common index matches
85  */
86  pips_debug(8,"same entities, and r1 path is shorter than r2 path\n");
87  while (res && !ENDP(ind1))
88  {
89  expression exp1 = EXPRESSION(CAR(ind1));
90  expression exp2 = EXPRESSION(CAR(ind2));
91 
93  {
94  res = true;
95  *exact_p = false;
96  }
97  else if(!expression_equal_p(exp1, exp2))
98  {
99  res = false;
100  *exact_p = true;
101  }
102 
103  POP(ind1);
104  POP(ind2);
105  }
106  }
107  else
108  {
109  res = false;
110  *exact_p = true;
111  }
112 
113  pips_debug(8, "end : r1 is %s a predecessor of r2 (%s exact)\n",
114  res ? "":"not", *exact_p ? "":"not");
115  return res;
116 }
117 
118 
120  cell c2, descriptor d2,
122  bool strict_p,
123  bool * exact_p)
124 {
125  reference r1 = cell_any_reference(c1);
126  reference r2 = cell_any_reference(c2);
127 
129  strict_p, exact_p);
130 }
131 
134  bool strict_p,
135  bool * exact_p)
136 {
137  reference r1 = effect_any_reference(eff1);
138  descriptor d1 = effect_descriptor(eff1);
139  reference r2 = effect_any_reference(eff2);
140  descriptor d2 = effect_descriptor(eff2);
141 
143  strict_p, exact_p);
144 }
145 
147  reference * output_ref,
148  descriptor * output_desc)
149 {
150  *output_ref = ref;
151  *output_desc = make_descriptor(is_descriptor_none,UU);
152 }
153 
155  cell * output_cell,
156  descriptor * output_desc)
157 {
158  *output_cell = input_cell;
159  *output_desc = make_descriptor(is_descriptor_none,UU);
160 }
161 
162 /*
163  @param c is a the simple cell for which we look an equivalent constant path
164  @param ptl is the list of points-to in which we search for constant paths
165  @param exact_p is a pointer towards a boolean. It is set to true if
166  the result is exact, and to false if it is an approximation,
167  either because the matching points-to sources found in ptl are
168  over-approximations of the preceding path of input_ref or because
169  the matching points-to have MAY approximation tag.
170  @return a list of constant path cells. It is a list because at a given
171  program point the cell may correspond to several constant paths.
172 
173 
174  original comment:
175  goal: see if cell c can be shortened by replacing its indirections
176  by their values when they are defined in ptl. For instance, p[0][0]
177  and (p,q,EXACT) is reduced to q[0]. And if (q,i,EXACT) is also
178  available, the reference is reduced to i. The reduced cell is less likely
179  to be invalidated by a write effect. The function is called "eval"
180  because its goal is to build an as constant as possible reference or
181  gap.
182 
183  I currently assume that points-to sinks are constant paths because
184  in the last example we should also have (p[0], i, EXACT) in the
185  points-to list. (BC)
186 
187  This function is called by effects to see if a memory access path
188  can be transformed into a constant. It should also be called by the
189  points-to analysis to see if a sink or a source can be preserved in
190  spite of write effects. This function should be called before
191  points_to_filter_effects() to reduce the number of anywhere
192  locations generated.
193 */
195  list ptl, bool *exact_p,
196  transformer __attribute__ ((unused)) t)
197 {
203 }
204 
205 
207 {
208  list le = NIL;
209  bool exact_p;
211 
212  if (effect_reference_dereferencing_p(ref, &exact_p))
213  {
214  pips_debug(8, "dereferencing case \n");
215  bool exact_p = false;
218  list l_aliased = effect_find_aliased_paths_with_pointer_values(eff, l_pv, &ctxt);
219  pips_debug_effects(8, "aliased effects\n", l_aliased);
220  reset_pv_context(&ctxt);
221 
222  FOREACH(EFFECT, eff_alias, l_aliased)
223  {
224  entity ent_alias = effect_entity(eff_alias);
225  if (undefined_pointer_value_entity_p(ent_alias)
226  || null_pointer_value_entity_p(ent_alias))
227  {
228  // currently interpret them as anywhere effects since these values
229  // are not yet well integrated in abstract locations lattice
230  // and in effects computations
231  // to be FIXED later.
232  le = CONS(EFFECT, make_anywhere_effect(copy_action(effect_action(eff_alias))), le);
233  free_effect(eff_alias);
234  }
235  else if (entity_abstract_location_p(effect_entity(eff_alias))
236  || !effect_reference_dereferencing_p(effect_any_reference(eff_alias), &exact_p)) {
237  le = CONS(EFFECT, eff_alias, le);
238  /* it should be a union here.
239  * However, we expect the caller
240  * to perform the contraction afterwards. */
241  }
242  else
243  free_effect(eff_alias);
244  }
245  gen_free_list(l_aliased);
246  }
247  else {
248  // functions that can be pointed by effect_dup_func:
249  // simple_effect_dup
250  // region_dup
251  // copy_effect
252  le = CONS(EFFECT, (*effect_dup_func)(eff), le);
253  }
254 
255  return le;
256 }
257 
258 #if false
259 /* Transform the cell list cl into an effect list, using information
260  * from effect eff and approximation information exact_p.
261  *
262  * The behavior should be generic, independent of the descriptor and
263  * effect kind.
264  */
265 static list cells_to_effects_according_to_effect(list cl, effect eff, bool exact_p)
266 {
267  list el = NIL;
269  descriptor d = effect_descriptor(eff);
270  action a = effect_action(eff);
271  FOREACH(CELL, c, cl) {
273  descriptor nd = copy_descriptor(d);
274  action na = copy_action(a);
275  effect e = make_effect(c, na, nap, nd);
277  el = CONS(EFFECT, e, el);
278  }
279  el = gen_nreverse(el);
280  return el;
281 }
282 #endif
283 
285 {
286  list le = NIL;
287  bool exact_p;
289 
290  pips_debug_effect(5, "input effect", eff);
291 
293  if(!points_to_list_bottom(ptl)) {
294  if (effect_reference_dereferencing_p(ref, &exact_p))
295  {
296  pips_debug(8, "dereferencing case \n");
297  bool exact_p = false;
298 #if false
302  else {
304  }
305 #endif
306 
308  points_to_list_list(ptl),
309  &exact_p, context);
310  if (ENDP(l_eval))
311  {
312  pips_debug(8, "no equivalent constant path found -> anywhere effect\n");
313  /* We have not found any equivalent constant path : it may point anywhere */
314  /* We should maybe contract these effects later. Is it done by the callers ? */
315  // le = CONS(EFFECT, make_anywhere_effect(copy_action(effect_action(eff))), le);
316  le = NIL; // A translation failure means an execution
317  // failure, at least according to the standard
318  }
319  else
320  {
321  /* make the resulting effects action to the current effect action */
322  // list l_eval_eff = cells_to_effects_according_to_effect(l_eval, eff, exact_p);
323 
324  if (effect_read_p(eff))
325  effects_to_read_effects(l_eval);
326  if (effect_may_p(eff))
327  effects_to_may_effects(l_eval);
328  le = gen_nconc(l_eval,le);
329  }
330  }
331  else
332  le = CONS(EFFECT, copy_effect(eff), le);
333  }
334  else {
335  /* This is dead code: no effects, do not modify le */
336  ;
337  }
338  return le;
339 
340 }
341 
342 
344 {
348 }
349 
350 /* for backward compatibility */
351 
352 list eval_cell_with_points_to(cell c, list ptl, bool *exact_p)
353 {
355  list l = NIL;
356 
357  FOREACH(EFFECT,eff, l_eff)
358  {
359  l = CONS(CELL, effect_cell(eff), l);
361  }
362  gen_full_free_list(l_eff);
363  return l;
364 }
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
action copy_action(action p)
ACTION.
Definition: effects.c:77
descriptor make_descriptor(enum descriptor_utype tag, void *val)
Definition: effects.c:433
void free_effect(effect p)
Definition: effects.c:451
bool effect_consistent_p(effect p)
Definition: effects.c:457
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
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
bool entity_abstract_location_p(entity al)
#define pips_debug_effects(level, message, l_eff)
#define pips_debug_effect(level, message, eff)
for debug
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)
void effects_to_may_effects(list)
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)
list simple_effect_to_constant_path_effects_with_points_to(effect eff)
Definition: eval.c:343
void simple_reference_to_simple_reference_conversion(reference ref, reference *output_ref, descriptor *output_desc)
Definition: eval.c:146
bool simple_cell_preceding_p(cell c1, descriptor d1, cell c2, descriptor d2, transformer current_precondition, bool strict_p, bool *exact_p)
Definition: eval.c:119
void simple_cell_to_simple_cell_conversion(cell input_cell, cell *output_cell, descriptor *output_desc)
Definition: eval.c:154
bool simple_cell_reference_preceding_p(reference r1, descriptor __attribute__((unused)) d1, reference r2, descriptor __attribute__((unused)) d2, transformer __attribute__((unused)) current_precondition, bool strict_p, bool *exact_p)
Definition: eval.c:60
list simple_effect_to_constant_path_effects_with_pointer_values(effect eff)
Definition: eval.c:206
list effect_to_constant_path_effects_with_points_to(effect eff, statement s, transformer context)
Definition: eval.c:284
list eval_simple_cell_with_points_to(cell c, descriptor __attribute__((unused)) d, list ptl, bool *exact_p, transformer __attribute__((unused)) t)
Definition: eval.c:194
bool path_preceding_p(effect eff1, effect eff2, transformer current_precondition, bool strict_p, bool *exact_p)
Definition: eval.c:132
list eval_cell_with_points_to(cell c, list ptl, bool *exact_p)
for backward compatibility
Definition: eval.c:352
void simple_cell_reference_with_address_of_cell_reference_translation(reference, descriptor, reference, descriptor, int, reference *, descriptor *, bool *)
#define effect_may_p(eff)
#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
bool undefined_pointer_value_entity_p(entity)
points_to_list load_pt_to_list(statement)
bool null_pointer_value_entity_p(entity)
#define cell_relations_list(x)
Definition: effects.h:549
#define cell_undefined
Definition: effects.h:430
#define effect_action(x)
Definition: effects.h:642
#define CELL(x)
CELL.
Definition: effects.h:424
@ is_descriptor_none
Definition: effects.h:576
#define effect_descriptor(x)
Definition: effects.h:646
#define descriptor_undefined
Definition: effects.h:559
#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
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
#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
#define UU
Definition: newgen_types.h:98
pv_context make_simple_pv_context(void)
cell_relations load_pv(statement)
list effect_find_aliased_paths_with_pointer_values(effect, list, pv_context *)
find all paths equivalent to eff cell in l_pv by performing a transitive closure
void reset_pv_context(pv_context *)
#define points_to_list_list(x)
#define points_to_list_bottom(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 expression_equal_p(expression e1, expression e2)
Syntactic equality e1==e2.
Definition: expression.c:1347
bool unbounded_expression_p(expression e)
Definition: expression.c:4329
#define transformer_undefined
Definition: ri.h:2847
#define reference_variable(x)
Definition: ri.h:2326
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define reference_indices(x)
Definition: ri.h:2328
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