PIPS
statement.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "ri-util.h"
#include "effects.h"
#include "effects-util.h"
#include "misc.h"
#include "properties.h"
#include "points-to.h"
+ Include dependency graph for statement.c:

Go to the source code of this file.

Functions

set full_copy_simple_pt_map (set m)
 FI: short term attempt at providing a deep copy to avoid sharing between sets. More...
 
pt_map full_copy_pt_map (pt_map in)
 
void init_statement_points_to_context ()
 
void push_statement_points_to_context (statement s, pt_map in)
 
void add_arc_to_statement_points_to_context (points_to pt)
 
void update_statement_points_to_context_with_arc (points_to pt)
 
int points_to_context_statement_line_number ()
 
pt_map points_to_context_statement_in ()
 
pt_map pop_statement_points_to_context (void)
 
void reset_statement_points_to_context ()
 
bool statement_points_to_context_defined_p ()
 
pt_map statement_to_points_to (statement s, pt_map pt_in)
 See points_to_statement() More...
 
pt_map declaration_statement_to_points_to (statement s, pt_map pt_in)
 See points_to_init() More...
 
pt_map instruction_to_points_to (instruction i, pt_map pt_in)
 See points_to_statement() More...
 
pt_map sequence_to_points_to (sequence seq, pt_map pt_in)
 
static void expand_points_to_domain (points_to_graph pt_t, points_to_graph pt_f)
 expand the domain of pt_f according to the domain of pt_t More...
 
void equalize_points_to_domains (points_to_graph pt_t, points_to_graph pt_f)
 Make sure that pt_t and pt_f have the same definition domain except if one of them is bottom. More...
 
pt_map test_to_points_to (test t, pt_map pt_in)
 Computing the points-to information after a test. More...
 
pt_map loop_to_points_to (loop l, pt_map pt_in)
 FI: I assume that pointers and pointer arithmetic cannot appear in a do loop, "do p=q, r, 1" is possible with "p", "q" and "r" pointing towards the same array... More...
 
pt_map whileloop_to_points_to (whileloop wl, pt_map pt_in)
 
pt_map any_loop_to_points_to (statement b, expression init, expression c, expression inc, pt_map pt_in)
 Perform the same k-limiting scheme for all kinds of loops. More...
 
pt_map new_any_loop_to_points_to (statement b, expression init, expression c, expression inc, pt_map pt_in)
 Perform the same k-limiting scheme for all kinds of loops. More...
 
pt_map k_limit_points_to (pt_map pt_out, int k)
 
pt_map unstructured_to_points_to (unstructured u, pt_map pt_in)
 
pt_map multitest_to_points_to (multitest mt, pt_map pt_in)
 
pt_map forloop_to_points_to (forloop fl, pt_map pt_in)
 

Variables

static stack statement_points_to_context = stack_undefined
 The input points-to information of a statement is updated by the analysis of the statement because of the on-demand approach. More...
 
static stack current_statement_points_to_context = stack_undefined
 

Function Documentation

◆ add_arc_to_statement_points_to_context()

void add_arc_to_statement_points_to_context ( points_to  pt)
Parameters
ptt

Definition at line 104 of file statement.c.

105 {
107  add_arc_to_pt_map(pt, in);
108  //update_points_to_graph_with_arc(pt, in);
109  pips_assert("in is consistent", consistent_pt_map_p(in));
110 }
#define add_arc_to_pt_map(a, s)
#define consistent_pt_map_p(s)
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
void * stack_head(const stack)
returns the item on top of stack s
Definition: stack.c:420
static stack statement_points_to_context
The input points-to information of a statement is updated by the analysis of the statement because of...
Definition: statement.c:87

References add_arc_to_pt_map, consistent_pt_map_p, pips_assert, stack_head(), and statement_points_to_context.

Referenced by add_arc_to_points_to_context(), and dereferencing_subscript_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ any_loop_to_points_to()

pt_map any_loop_to_points_to ( statement  b,
expression  init,
expression  c,
expression  inc,
pt_map  pt_in 
)

Perform the same k-limiting scheme for all kinds of loops.

The do while loop must use an external special treatment for the first iteration.

Derived from points_to_forloop() and from Amira's work.

pt_in is modified by side effects.

First, enter or skip the loop: initialization + condition check

Comput pt_out as loop invariant: pt_out holds at the beginning of the loop body.

pt_out(i) = f(pt_out(i-1)) U pt_out(i-1)

prev = pt_out(i-1)

Note: the pt_out variable is also used to carry the loop exit points-to set.

prev receives the current points-to information, pt_out

Depending on the kind of loops, execute the body and then possibly the incrementation and the condition

Merge the previous resut and the current result.

Check convergence

Add the last iteration to obtain the pt_out holding when exiting the loop

FI: I suppose that p[i] is replaced by p[*] and that MAY/MUST information is changed accordingly.

Parameters
initnit
incnc
pt_int_in

Definition at line 653 of file statement.c.

658 {
659  pt_map pt_out = pt_in;
660 
661  if(points_to_graph_bottom(pt_in)) {
662  (void) statement_to_points_to(b, pt_in);
663  }
664  else {
665  int i = 0;
666  // FI: k is linked to the cycles in points-to graph, and should not
667  // be linked to the number of convergence iterations. I assume here
668  // that the minimal number of iterations is greater than the
669  // k-limiting factor
670  int k = get_int_property("POINTS_TO_PATH_LIMIT")
671  + get_int_property("POINTS_TO_SUBSCRIPT_LIMIT")
672  + get_int_property("POINTS_TO_OUT_DEGREE_LIMIT")
673  +10; // Safety margin: might be set to max of both properties + 1 or 2...
674 
675  /* First, enter or skip the loop: initialization + condition check */
677  pt_out = expression_to_points_to(init, pt_out, true);
678  pt_map pt_out_skip = full_copy_pt_map(pt_out);
679  if(!expression_undefined_p(c)) {
680  pt_out = expression_to_points_to(c, pt_out, true);
681  pt_out = condition_to_points_to(c, pt_out, true);
682  pt_out_skip = condition_to_points_to(c, pt_out_skip, false);
683  }
684 
685  /* Comput pt_out as loop invariant: pt_out holds at the beginning of
686  * the loop body.
687  *
688  * pt_out(i) = f(pt_out(i-1)) U pt_out(i-1)
689  *
690  * prev = pt_out(i-1)
691  *
692  * Note: the pt_out variable is also used to carry the loop exit
693  * points-to set.
694  */
695  pt_map prev = new_pt_map();
696  // FI: it should be a while loop to reach convergence
697  // FI: I keep it a for loop for safety
698  bool fix_point_p = false;
699  for(i = 0; i<k+2 ; i++) {
700  /* prev receives the current points-to information, pt_out */
701  clear_pt_map(prev);
702  prev = assign_pt_map(prev, pt_out);
703  clear_pt_map(pt_out);
704 
705  /* Depending on the kind of loops, execute the body and then
706  possibly the incrementation and the condition */
707  // FI: here, storage_p would be useful to avoid unnecessary
708  // storage and update for each substatement at each iteration k
709  pt_out = statement_to_points_to(b, prev);
710  if(!expression_undefined_p(inc))
711  pt_out = expression_to_points_to(inc, pt_out, true);
712  // FI: should be condition_to_points_to() for conditions such as
713  // while(p!=q);
714  // The condition is not always defined (do loops)
715  if(!expression_undefined_p(c)) {
716  pt_out = condition_to_points_to(c, pt_out, true);
718  }
719 
720  /* Merge the previous resut and the current result. */
721  // FI: move to pt_map
722  pt_out = merge_points_to_graphs(prev, pt_out);
723 
724  pt_out = normalize_points_to_graph(pt_out);
726 
727  // pips_assert("", consistent_points_to_graph_p(pt_out));
728 
729  /* Check convergence */
731  fix_point_p = true;
732  /* Add the last iteration to obtain the pt_out holding when
733  exiting the loop */
734  pt_out = statement_to_points_to(b, prev);
735 
737  if(!expression_undefined_p(inc))
738  pt_out = expression_to_points_to(inc, pt_out, true);
739 
741  if(!expression_undefined_p(c))
742  pt_out = condition_to_points_to(c, pt_out, false);
743 
745  break;
746  }
747  else {
748  ifdebug(1) {
749  pips_debug(1, "\n\nAt iteration i=%d:\n\n", i);
750  print_points_to_set("Loop points-to set prev:\n",
751  points_to_graph_set(prev));
752  print_points_to_set("Loop points-to set pt_out:\n",
753  points_to_graph_set(pt_out));
754  }
755  }
756  }
757 
758  if(!fix_point_p) {
759  print_points_to_set("Loop points-to set prev:\n", points_to_graph_set(prev));
760  print_points_to_set("Loop points-to set pt_out:\n", points_to_graph_set(pt_out));
761  pips_internal_error("Loop convergence not reached in %d iterations.\n", i);
762  }
763 
764  /* FI: I suppose that p[i] is replaced by p[*] and that MAY/MUST
765  information is changed accordingly. */
767 
768  // pips_assert("", consistent_points_to_graph_p(pt_out));
769 
770  pt_out = merge_points_to_graphs(pt_out, pt_out_skip);
771  }
772 
773  // pips_assert("", consistent_points_to_graph_p(pt_out));
774 
775  return pt_out;
776 }
int get_int_property(const string)
#define clear_pt_map(pt)
#define assign_pt_map(x, y)
#define new_pt_map()
set points_to_independent_store(set s)
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_internal_error
Definition: misc-local.h:149
bool set_equal_p(const set, const set)
returns whether s1 == s2
Definition: set.c:316
pt_map condition_to_points_to(expression c, pt_map in, bool true_p)
Update points-to set "in" according to the content of the expression using side effects.
Definition: expression.c:2512
pt_map expression_to_points_to(expression e, pt_map pt_in, bool side_effect_p)
Update pt_in and pt_out according to expression e.
Definition: expression.c:115
pt_map full_copy_pt_map(pt_map in)
Definition: statement.c:67
pt_map statement_to_points_to(statement s, pt_map pt_in)
See points_to_statement()
Definition: statement.c:154
void upgrade_approximations_in_points_to_set(pt_map)
When arcs have been removed from a points-to relation, the approximations of remaining arcs may not c...
pt_map normalize_points_to_graph(pt_map)
For the time being, control the out-degree of the vertices in points-to graph "ptg" and fuse the vert...
void print_points_to_set(string, set)
pt_map remove_unreachable_stub_vertices_in_points_to_graph(pt_map)
bool consistent_points_to_graph_p(points_to_graph)
pt_map merge_points_to_graphs(pt_map, pt_map)
#define points_to_graph_bottom(x)
#define points_to_graph_set(x)
static int init
Maximal value set for Fortran 77.
Definition: entity.c:320
#define expression_undefined_p(x)
Definition: ri.h:1224
#define ifdebug(n)
Definition: sg.c:47

References assign_pt_map, clear_pt_map, condition_to_points_to(), consistent_points_to_graph_p(), expression_to_points_to(), expression_undefined_p, full_copy_pt_map(), get_int_property(), ifdebug, init, merge_points_to_graphs(), new_pt_map, normalize_points_to_graph(), pips_assert, pips_debug, pips_internal_error, points_to_graph_bottom, points_to_graph_set, points_to_independent_store(), print_points_to_set(), remove_unreachable_stub_vertices_in_points_to_graph(), set_equal_p(), statement_to_points_to(), and upgrade_approximations_in_points_to_set().

Referenced by forloop_to_points_to(), loop_to_points_to(), and whileloop_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ declaration_statement_to_points_to()

pt_map declaration_statement_to_points_to ( statement  s,
pt_map  pt_in 
)

See points_to_init()

pt_in is modified by side-effects and returned

generate points-to due to the initialisation

AM/FI: abnormal sharing (lhs); the reference may be reused in the cel...

free_expression(lhs);

The initialization expression may use pointers, directly or indirectly via struct and arrays.

Take care of expressions in array sizing (see array12.c)

Parameters
pt_int_in

Definition at line 262 of file statement.c.

263 {
264  pt_map pt_out = pt_in;
265  //set pt_out = set_generic_make(set_private, points_to_equal_p, points_to_rank);
266  list l = NIL;
267  //bool type_sensitive_p = !get_bool_property("ALIASING_ACROSS_TYPES");
268 
269  list l_decls = statement_declarations(s);
270 
271  pips_debug(1, "declaration statement \n");
272 
273  FOREACH(ENTITY, e, l_decls) {
275  if(pointer_type_p(et)
277  || struct_type_p(et)
278  || array_of_struct_type_p(et)) {
279  if( !storage_rom_p(entity_storage(e)) ) {
280  // FI: could be simplified with variable_initial_expression()
281  value v_init = entity_initial(e);
282  /* generate points-to due to the initialisation */
283  if(value_expression_p(v_init)){
284  expression exp_init = value_expression(v_init);
287  // See C standard for type compatibility + PIPS idiosyncrasies
288  // This should be extended to cope with the C type hierarchy
289  // accept side effects
290  pt_out = expression_to_points_to(exp_init, pt_out, true);
291  //if(array_pointer_type_equal_p(et, it)
292  //if(concrete_type_equal_p(et, it)
293  if(type_structurally_equal_p(et, it)
294  || array_pointer_type_equal_p(et, it)
295  || type_void_star_p(et) || type_void_star_p(it)
296  || integer_type_p(it)
297  || (char_star_type_p(et) && string_type_p(it))
298  || overloaded_type_p(it)) // PIPS own compatibility...
299  pt_out = assignment_to_points_to(lhs,
300  exp_init,
301  pt_out);
302  else {
303  pips_user_warning("Type mismatch for initialization of \"%s\" at line %d.\n",
304  entity_user_name(e),
306  clear_pt_map(pt_out);
307  points_to_graph_bottom(pt_out) = true;
308  }
309  /* AM/FI: abnormal sharing (lhs); the reference may be
310  reused in the cel... */
311  /* free_expression(lhs); */
312  }
313  else {
315  // C Standard: if e is a static pointer, it is implicly
316  // initialized to NULL
317  if(pointer_type_p(et) && variable_static_p(e)) {
318  cell source = CELL(CAR(l));
319  cell sink = make_null_cell();
320  points_to pt = make_points_to(source, sink,
323  add_arc_to_pt_map(pt, pt_out);
324  // The declared variable is local
325  // add_arc_to_points_to_context(copy_points_to(pt));
326  }
327  else {
328  FOREACH(CELL, source, l) {
329  cell sink = cell_to_nowhere_sink(source);
330  points_to pt = make_points_to(source, sink,
333  add_arc_to_pt_map(pt, pt_out);
334  // The declared variable is local
335  // add_arc_to_points_to_context(copy_points_to(pt));
336  }
337  }
338  }
339  }
340  }
341  else {
342  /* The initialization expression may use pointers, directly or
343  indirectly via struct and arrays. */
345  if(!expression_undefined_p(ie)) {
346  pt_out = expression_to_points_to(ie, pt_out, true);
347  free_expression(ie);
348  }
349  }
350  /* Take care of expressions in array sizing (see array12.c) */
351  if(array_type_p(et)) {
352  variable ev = type_variable(et);
353  list dl = variable_dimensions(ev);
354  FOREACH(DIMENSION, d, dl) {
357  pt_out = expression_to_points_to(l, pt_out, true);
358  pt_out = expression_to_points_to(u, pt_out, true);
359  }
360  }
361  }
362 
363  return pt_out;
364 }
approximation make_approximation_exact(void)
Definition: effects.c:185
descriptor make_descriptor_none(void)
Definition: effects.c:442
points_to make_points_to(cell a1, cell a2, approximation a3, descriptor a4)
void free_expression(expression p)
Definition: ri.c:853
cell cell_to_nowhere_sink(cell source)
assuming source is a reference to a pointer, build the corresponding sink when the pointer is not ini...
#define CELL(x)
CELL.
Definition: effects.h:424
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#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_user_warning
Definition: misc-local.h:146
pt_map assignment_to_points_to(expression lhs, expression rhs, pt_map pt_in)
Definition: expression.c:1163
int points_to_context_statement_line_number()
Definition: statement.c:120
cell make_null_cell(void)
Definition: sinks.c:95
list variable_to_pointer_locations(entity)
variable.c
Definition: variable.c:66
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
bool array_type_p(type)
Definition: type.c:2942
bool type_void_star_p(type)
Definition: type.c:5765
type expression_to_type(expression)
For an array declared as int a[10][20], the type returned for a[i] is int [20].
Definition: type.c:2486
bool array_of_pointers_type_p(type)
Definition: type.c:3025
bool integer_type_p(type)
Definition: type.c:3298
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 type_structurally_equal_p(type, type)
Type t1 and t2 are equal if their basic concrete components are equal.
Definition: type.c:586
bool array_pointer_type_equal_p(type, type)
assume that a pointer to type x is equal to a 1-D array of x
Definition: type.c:609
expression variable_initial_expression(entity)
Returns a copy of the initial (i.e.
Definition: variable.c:1899
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
type compute_basic_concrete_type(type)
computes a new type which is the basic concrete type of the input type (this new type is not stored i...
Definition: type.c:3556
bool overloaded_type_p(type)
Returns true if t is a variable type with a basic overloaded.
Definition: type.c:2666
bool char_star_type_p(type)
Beware of typedefs.
Definition: type.c:5774
bool string_type_p(type)
Definition: type.c:2854
bool array_of_struct_type_p(type)
Definition: type.c:3133
bool variable_static_p(entity)
true if v appears in a SAVE statement, or in a DATA statement, or is declared static i C.
Definition: variable.c:1579
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define dimension_lower(x)
Definition: ri.h:980
#define type_variable(x)
Definition: ri.h:2949
#define entity_storage(x)
Definition: ri.h:2794
#define dimension_upper(x)
Definition: ri.h:982
#define variable_dimensions(x)
Definition: ri.h:3122
#define statement_declarations(x)
Definition: ri.h:2460
#define storage_rom_p(x)
Definition: ri.h:2525
#define value_expression_p(x)
Definition: ri.h:3080
#define value_expression(x)
Definition: ri.h:3082
#define entity_initial(x)
Definition: ri.h:2796
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References add_arc_to_pt_map, array_of_pointers_type_p(), array_of_struct_type_p(), array_pointer_type_equal_p(), array_type_p(), assignment_to_points_to(), CAR, CELL, cell_to_nowhere_sink(), char_star_type_p(), clear_pt_map, compute_basic_concrete_type(), DIMENSION, dimension_lower, dimension_upper, ENTITY, entity_basic_concrete_type(), entity_initial, entity_storage, entity_to_expression(), entity_user_name(), expression_to_points_to(), expression_to_type(), expression_undefined_p, FOREACH, free_expression(), integer_type_p(), make_approximation_exact(), make_descriptor_none(), make_null_cell(), make_points_to(), NIL, overloaded_type_p(), pips_debug, pips_user_warning, pointer_type_p(), points_to_context_statement_line_number(), points_to_graph_bottom, statement_declarations, storage_rom_p, string_type_p(), struct_type_p(), type_structurally_equal_p(), type_variable, type_void_star_p(), value_expression, value_expression_p, variable_dimensions, variable_initial_expression(), variable_static_p(), and variable_to_pointer_locations().

Referenced by statement_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ equalize_points_to_domains()

void equalize_points_to_domains ( points_to_graph  pt_t,
points_to_graph  pt_f 
)

Make sure that pt_t and pt_f have the same definition domain except if one of them is bottom.

Parameters
pt_tt_t
pt_ft_f

Definition at line 479 of file statement.c.

480 {
481  if(!points_to_graph_bottom(pt_t)) {
482  if(!points_to_graph_bottom(pt_f)) {
483  expand_points_to_domain(pt_t, pt_f);
484  expand_points_to_domain(pt_f, pt_t);
485  }
486  }
487 }
static void expand_points_to_domain(points_to_graph pt_t, points_to_graph pt_f)
expand the domain of pt_f according to the domain of pt_t
Definition: statement.c:450

References expand_points_to_domain(), and points_to_graph_bottom.

Referenced by test_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ expand_points_to_domain()

static void expand_points_to_domain ( points_to_graph  pt_t,
points_to_graph  pt_f 
)
static

expand the domain of pt_f according to the domain of pt_t

Definition at line 450 of file statement.c.

451 {
452  set s_t = points_to_graph_set(pt_t);
453  set s_f = points_to_graph_set(pt_f);
454  SET_FOREACH(points_to, a_t, s_t) {
455  cell c_t = points_to_source(a_t);
456  bool found_p = false;
457  SET_FOREACH(points_to, a_f, s_f) {
458  cell c_f = points_to_source(a_f);
459  if(points_to_cell_equal_p(c_t, c_f)) {
460  found_p = true;
461  break;
462  }
463  }
464  if(!found_p) {
465  reference r_t = cell_any_reference(c_t);
466  entity v_t = reference_variable(r_t);
467  if(formal_parameter_p(v_t) || entity_stub_sink_p(v_t)) {
469  pt_f = pointer_assignment_to_points_to(e_t, e_t, pt_f);
470  if(points_to_graph_bottom(pt_f))
471  pips_internal_error("Unexpected information loss.");
472  }
473  }
474  }
475 }
bool entity_stub_sink_p(entity e)
test if an entity is a stub sink for a formal parameter e.g.
reference cell_any_reference(cell)
API for reference.
Definition: effects.c:77
bool points_to_cell_equal_p(cell, cell)
Definition: points_to.c:916
#define SET_FOREACH(type_name, the_item, the_set)
enumerate set elements in their internal order.
Definition: newgen_set.h:78
pt_map pointer_assignment_to_points_to(expression lhs, expression rhs, pt_map pt_in)
Definition: expression.c:1437
#define points_to_source(x)
expression reference_to_expression(reference r)
Definition: expression.c:196
bool formal_parameter_p(entity)
Definition: variable.c:1489
#define reference_variable(x)
Definition: ri.h:2326
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59

References cell_any_reference(), entity_stub_sink_p(), formal_parameter_p(), pips_internal_error, pointer_assignment_to_points_to(), points_to_cell_equal_p(), points_to_graph_bottom, points_to_graph_set, points_to_source, reference_to_expression(), reference_variable, and SET_FOREACH.

Referenced by equalize_points_to_domains().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ forloop_to_points_to()

pt_map forloop_to_points_to ( forloop  fl,
pt_map  pt_in 
)
Parameters
fll
pt_int_in

Definition at line 974 of file statement.c.

975 {
976  pt_map pt_out = pt_in;
977  statement b = forloop_body(fl);
980  expression inc = forloop_increment(fl);
981 
982  pt_out = any_loop_to_points_to(b, init, c, inc, pt_in);
983  return pt_out;
984 }
pt_map any_loop_to_points_to(statement b, expression init, expression c, expression inc, pt_map pt_in)
Perform the same k-limiting scheme for all kinds of loops.
Definition: statement.c:653
#define forloop_initialization(x)
Definition: ri.h:1366
#define forloop_increment(x)
Definition: ri.h:1370
#define forloop_condition(x)
Definition: ri.h:1368
#define forloop_body(x)
Definition: ri.h:1372

References any_loop_to_points_to(), forloop_body, forloop_condition, forloop_increment, forloop_initialization, and init.

Referenced by instruction_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ full_copy_pt_map()

pt_map full_copy_pt_map ( pt_map  in)
Parameters
inn

Definition at line 67 of file statement.c.

68 {
69  // Dynamic type check
71  pips_assert("\"in\" is a points_to_graph", n==points_to_graph_domain);
72  pt_map out = new_pt_map();
73  set in_s = points_to_graph_set(in);
74  set out_s = points_to_graph_set(out);
75  SET_FOREACH(points_to, pt, in_s) {
76  points_to npt = copy_points_to(pt);
77  set_add_element(out_s, out_s, (void *) npt);
78  }
80  return out;
81 }
points_to copy_points_to(points_to p)
POINTS_TO.
static FILE * out
Definition: alias_check.c:128
set set_add_element(set, const set, const void *)
Definition: set.c:152
#define points_to_graph_domain_number(x)
#define points_to_graph_domain
Definition: print.c:373

References copy_points_to(), new_pt_map, out, pips_assert, points_to_graph_bottom, points_to_graph_domain, points_to_graph_domain_number, points_to_graph_set, set_add_element(), and SET_FOREACH.

Referenced by any_loop_to_points_to(), boolean_intrinsic_call_condition_to_points_to(), init_points_to_context(), intrinsic_call_to_points_to(), new_any_loop_to_points_to(), new_points_to_unstructured(), statement_to_points_to(), ternary_intrinsic_call_to_points_to_sinks(), and test_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ full_copy_simple_pt_map()

set full_copy_simple_pt_map ( set  m)

FI: short term attempt at providing a deep copy to avoid sharing between sets.

statement.c

If elements are shared, it quickly becomes impossible to deep free any set.

Definition at line 50 of file statement.c.

51 {
53  /*
54  HASH_MAP(k, v, {
55  points_to pt = (points_to) k;
56  points_to npt = copy_points_to(pt);
57  hash_put( out->table, (void *) npt, (void *) npt );
58  }, m->table);
59  */
60  SET_FOREACH(points_to, pt, m) {
61  points_to npt = copy_points_to(pt);
62  set_add_element(out, out, (void *) npt);
63  }
64  return out;
65 }
#define new_simple_pt_map()

References copy_points_to(), new_simple_pt_map, out, set_add_element(), and SET_FOREACH.

+ Here is the call graph for this function:

◆ init_statement_points_to_context()

void init_statement_points_to_context ( void  )

Definition at line 90 of file statement.c.

91 {
92  pips_assert("statement_points_to_context is undefined",
96 }
stack stack_make(int, int, int)
allocation
Definition: stack.c:246
#define stack_undefined_p(s)
Definition: newgen_stack.h:56
static stack current_statement_points_to_context
Definition: statement.c:88
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362

References current_statement_points_to_context, pips_assert, points_to_graph_domain, stack_make(), stack_undefined_p, statement_domain, and statement_points_to_context.

Referenced by generic_points_to_analysis().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ instruction_to_points_to()

pt_map instruction_to_points_to ( instruction  i,
pt_map  pt_in 
)

See points_to_statement()

pt_in is modified by side-effects and returned

Parameters
pt_int_in

Definition at line 370 of file statement.c.

371 {
372  pt_map pt_out = pt_in;
373  tag it = instruction_tag(i);
374  switch(it) {
377  pt_out = sequence_to_points_to(seq, pt_in);
378  break;
379  }
380  case is_instruction_test: {
381  test t = instruction_test(i);
382  pt_out = test_to_points_to(t, pt_in);
383  break;
384  }
385  case is_instruction_loop: {
386  loop l = instruction_loop(i);
387  pt_out = loop_to_points_to(l, pt_in);
388  break;
389  }
392  pt_out = whileloop_to_points_to(wl, pt_in);
393  break;
394  }
395  case is_instruction_goto: {
396  pips_internal_error("Go to instructions should have been removed "
397  "before the analysis is started\n");
398  break;
399  }
400  case is_instruction_call: {
401  call c = instruction_call(i);
402  if(points_to_graph_bottom(pt_in))
403  pt_out = pt_in;
404  else
405  pt_out = call_to_points_to(c, pt_out, NIL, true);
406  break;
407  }
410  pt_out = unstructured_to_points_to(u, pt_in);
411  break;
412  }
414  pips_internal_error("Not implemented\n");
415  break;
416  }
417  case is_instruction_forloop: {
419  pt_out = forloop_to_points_to(fl, pt_in);
420  break;
421  }
424  if(points_to_graph_bottom(pt_in))
425  pt_out = pt_in;
426  else
427  pt_out = expression_to_points_to(e, pt_in, true);
428  break;
429  }
430  default:
431  pips_internal_error("Unexpected instruction tag %d\n", it);
432  }
433  return pt_out;
434 }
int tag
TAG.
Definition: newgen_types.h:92
pt_map call_to_points_to(call c, pt_map pt_in, list el, bool side_effect_p)
Three different kinds of calls are distinguished:
Definition: expression.c:306
pt_map loop_to_points_to(loop l, pt_map pt_in)
FI: I assume that pointers and pointer arithmetic cannot appear in a do loop, "do p=q,...
Definition: statement.c:573
pt_map whileloop_to_points_to(whileloop wl, pt_map pt_in)
Definition: statement.c:604
pt_map sequence_to_points_to(sequence seq, pt_map pt_in)
Definition: statement.c:436
pt_map forloop_to_points_to(forloop fl, pt_map pt_in)
Definition: statement.c:974
pt_map unstructured_to_points_to(unstructured u, pt_map pt_in)
Definition: statement.c:958
pt_map test_to_points_to(test t, pt_map pt_in)
Computing the points-to information after a test.
Definition: statement.c:496
#define instruction_loop(x)
Definition: ri.h:1520
@ is_instruction_goto
Definition: ri.h:1473
@ is_instruction_unstructured
Definition: ri.h:1475
@ is_instruction_whileloop
Definition: ri.h:1472
@ is_instruction_expression
Definition: ri.h:1478
@ is_instruction_test
Definition: ri.h:1470
@ is_instruction_multitest
Definition: ri.h:1476
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_sequence
Definition: ri.h:1469
@ is_instruction_forloop
Definition: ri.h:1477
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define instruction_sequence(x)
Definition: ri.h:1514
#define instruction_forloop(x)
Definition: ri.h:1538
#define instruction_expression(x)
Definition: ri.h:1541
#define instruction_whileloop(x)
Definition: ri.h:1523
#define instruction_call(x)
Definition: ri.h:1529
#define instruction_test(x)
Definition: ri.h:1517
#define instruction_unstructured(x)
Definition: ri.h:1532

References call_to_points_to(), expression_to_points_to(), forloop_to_points_to(), instruction_call, instruction_expression, instruction_forloop, instruction_loop, instruction_sequence, instruction_tag, instruction_test, instruction_unstructured, instruction_whileloop, is_instruction_call, is_instruction_expression, is_instruction_forloop, is_instruction_goto, is_instruction_loop, is_instruction_multitest, is_instruction_sequence, is_instruction_test, is_instruction_unstructured, is_instruction_whileloop, loop_to_points_to(), NIL, pips_internal_error, points_to_graph_bottom, sequence_to_points_to(), test_to_points_to(), unstructured_to_points_to(), and whileloop_to_points_to().

Referenced by statement_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ k_limit_points_to()

pt_map k_limit_points_to ( pt_map  pt_out,
int  k 
)
Parameters
pt_outt_out

Definition at line 912 of file statement.c.

913 {
914  //bool type_sensitive_p = !get_bool_property("ALIASING_ACROSS_TYPES");
915  //entity anywhere = entity_undefined;
916  set pt_out_s = points_to_graph_set(pt_out);
917 
918  SET_FOREACH(points_to, pt, pt_out_s){
919  cell sc = points_to_source(pt);
920  reference sr = cell_any_reference(sc);
921  list sl = reference_indices(sr);
922 
923  cell kc = points_to_sink(pt);
924  reference kr = cell_any_reference(kc);
925  list kl = reference_indices(kr);
926 
927  if((int)gen_length(sl)>k){
928  bool to_be_freed = false;
929  type sc_type = cell_to_type(sc, &to_be_freed);
930  sc = make_anywhere_cell(sc_type);
931  if(to_be_freed) free_type(sc_type);
932  }
933 
934  if((int)gen_length(kl)>k){
935  bool to_be_freed = false;
936  type kc_type = cell_to_type(kc, &to_be_freed);
937  kc = make_anywhere_cell(kc_type);
938  if(to_be_freed) free_type(kc_type);
939  }
940 
941  points_to npt = make_points_to(sc, kc,
944  if(!points_to_equal_p(npt,pt)){
945  // FC: why assigning pt_out to itself?
946  pt_out = remove_arc_from_pt_map_(pt, pt_out);
947  pt_out = remove_arc_from_pt_map_(npt, pt_out);
948  }
949  else {
950  // FI: memory leak
951  // free_points_to(npt);
952  }
953  }
954  return pt_out;
955 }
approximation copy_approximation(approximation p)
APPROXIMATION.
Definition: effects.c:132
void free_type(type p)
Definition: ri.c:2658
cell make_anywhere_cell(type t)
type cell_to_type(cell, bool *)
Definition: type.c:513
size_t gen_length(const list l)
Definition: list.c:150
#define remove_arc_from_pt_map_(a, s)
int points_to_equal_p(const void *, const void *)
returns true if two points-to arcs "vpt1" and "vpt2" are equal.
Definition: points_to_set.c:98
#define points_to_approximation(x)
#define points_to_sink(x)
#define reference_indices(x)
Definition: ri.h:2328

References cell_any_reference(), cell_to_type(), copy_approximation(), free_type(), gen_length(), make_anywhere_cell(), make_descriptor_none(), make_points_to(), points_to_approximation, points_to_equal_p(), points_to_graph_set, points_to_sink, points_to_source, reference_indices, remove_arc_from_pt_map_, and SET_FOREACH.

+ Here is the call graph for this function:

◆ loop_to_points_to()

pt_map loop_to_points_to ( loop  l,
pt_map  pt_in 
)

FI: I assume that pointers and pointer arithmetic cannot appear in a do loop, "do p=q, r, 1" is possible with "p", "q" and "r" pointing towards the same array...

Let's hope the do loop conversion does not catch such cases.

loop range expressions may require some points-to information See for instance Pointers/Mensi.sub/array_init02.c

Side effects might have to be taken into account... But side effects should also prevent PIPS from transforming a for loop into a do loop.

Parameters
pt_int_in

Definition at line 573 of file statement.c.

574 {
575  pt_map pt_out = pt_in;
576  statement b = loop_body(l);
577  //bool store = false;
578  //pt_out = points_to_loop(l, pt_in, store);
579 
580  /* loop range expressions may require some points-to information
581  * See for instance Pointers/Mensi.sub/array_init02.c
582  *
583  * Side effects might have to be taken into account... But side
584  * effects should also prevent PIPS from transforming a for loop
585  * into a do loop.
586  */
587  range r = loop_range(l);
589  expression bound = range_upper(r);
590  expression inc = range_increment(r);
591  pt_in = expression_to_points_to(init, pt_in, false);
592  pt_in = expression_to_points_to(bound, pt_in, false);
593  pt_in = expression_to_points_to(inc, pt_in, false);
594 
595  pt_out = any_loop_to_points_to(b,
599  pt_in);
600 
601  return pt_out;
602 }
#define loop_body(x)
Definition: ri.h:1644
#define range_upper(x)
Definition: ri.h:2290
#define range_increment(x)
Definition: ri.h:2292
#define expression_undefined
Definition: ri.h:1223
#define range_lower(x)
Definition: ri.h:2288
#define loop_range(x)
Definition: ri.h:1642

References any_loop_to_points_to(), expression_to_points_to(), expression_undefined, init, loop_body, loop_range, range_increment, range_lower, and range_upper.

Referenced by instruction_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ multitest_to_points_to()

pt_map multitest_to_points_to ( multitest  mt,
pt_map  pt_in 
)
Parameters
mtt
pt_int_in

Definition at line 967 of file statement.c.

968 {
969  pt_map pt_out = pt_in;
970  pips_internal_error("Not implemented yet for multitest %p\n", mt);
971  return pt_out;
972 }

References pips_internal_error.

◆ new_any_loop_to_points_to()

pt_map new_any_loop_to_points_to ( statement  b,
expression  init,
expression  c,
expression  inc,
pt_map  pt_in 
)

Perform the same k-limiting scheme for all kinds of loops.

The do while loop must use an external special treatment for the first iteration.

Derived from the initial any_loop_to_points_to(): the iteration scheme is slighlty different but we end up with the same final iteration with all unioned states. Seems problematic at least in the presence of calls to free() because iter() is never normalized and always introduces new vertices and arcs in "pt_out". See list05.c.

pt_in is modified by side effects.

First, enter or skip the loop: initialization + condition check

Compute pt_out as loop invariant: pt_out holds at the beginning of the loop body.

pt_out(i) = pt_out(i-1) U pt_iter(i)

pt_iter(i) = f(pt_iter(i-1))

pt_prev == pt_iter(i-1), pt_out_prev == pt_out(i-1)

Note: the pt_out variable is also used to carry the loop exit points-to set.

prev receives the current points-to information, pt_iter

Depending on the kind of loop, execute the body and then possibly the incrementation and the condition

Merge the previous resut and the current result.

Check convergence

Add the last iteration to obtain the pt_out holding when exiting the loop

FI: I suppose that p[i] is replaced by p[*] and that MAY/MUST information is changed accordingly.

Parameters
initnit
incnc
pt_int_in

Definition at line 792 of file statement.c.

797 {
798  // return old_any_loop_to_points_to(b, init, c, inc, pt_in);
799  pt_map pt_out = pt_in;
800 
801  if(points_to_graph_bottom(pt_in)) {
802  (void) statement_to_points_to(b, pt_in);
803  }
804  else {
805  int i = 0;
806  // FI: k is linked to the cycles in points-to graph, and should not
807  // be linked to the number of convergence iterations. I assume here
808  // that the minimal number of iterations is greater than the
809  // k-limiting factor
810  int k = get_int_property("POINTS_TO_PATH_LIMIT")
811  + get_int_property("POINTS_TO_SUBSCRIPT_LIMIT")
812  + get_int_property("POINTS_TO_OUT_DEGREE_LIMIT")
813  +10; // Safety margin: might be set to max of both properties + 1 or 2...
814 
815  /* First, enter or skip the loop: initialization + condition check */
817  pt_out = expression_to_points_to(init, pt_out, true);
818  pt_map pt_out_skip = full_copy_pt_map(pt_out);
819  if(!expression_undefined_p(c)) {
820  pt_out = condition_to_points_to(c, pt_out, true);
821  pt_out_skip = condition_to_points_to(c, pt_out_skip, false);
822  }
823 
824  /* Compute pt_out as loop invariant: pt_out holds at the beginning of
825  * the loop body.
826  *
827  * pt_out(i) = pt_out(i-1) U pt_iter(i)
828  *
829  * pt_iter(i) = f(pt_iter(i-1))
830  *
831  * pt_prev == pt_iter(i-1), pt_out_prev == pt_out(i-1)
832  *
833  * Note: the pt_out variable is also used to carry the loop exit
834  * points-to set.
835  */
836  pt_map pt_out_prev = new_pt_map();
837  pt_map prev = new_pt_map();
838  pt_map pt_iter = new_pt_map();
839  pt_iter = assign_pt_map(pt_iter, pt_out);
840 
841  // FI: it should be a while loop to reach convergence
842  // FI: I keep it a for loop for safety
843  bool fix_point_p = false;
844  for(i = 0; i<k+2 ; i++) {
845  /* prev receives the current points-to information, pt_iter */
846  clear_pt_map(prev);
847  prev = assign_pt_map(prev, pt_iter);
848  clear_pt_map(pt_iter);
849 
850  /* Depending on the kind of loop, execute the body and then
851  possibly the incrementation and the condition */
852  // FI: here, storage_p would be useful to avoid unnecessary
853  // storage and update for each substatement at each iteration k
854  pt_iter = statement_to_points_to(b, prev);
855  if(!expression_undefined_p(inc))
856  pt_iter = expression_to_points_to(inc, pt_iter, true);
857  // FI: should be condition_to_points_to() for conditions such as
858  // while(p!=q);
859  // The condition is not always defined (do loops)
860  if(!expression_undefined_p(c))
861  pt_iter = condition_to_points_to(c, pt_iter, true);
862 
863  /* Merge the previous resut and the current result. */
864  // FI: move to pt_map
865  pt_out_prev = assign_pt_map(pt_out_prev, pt_out);
866  pt_out = merge_points_to_graphs(pt_out, pt_iter);
867 
868  pt_out = normalize_points_to_graph(pt_out);
869 
870  /* Check convergence */
871  if(set_equal_p(points_to_graph_set(pt_out_prev),
872  points_to_graph_set(pt_out))) {
873  fix_point_p = true;
874  /* Add the last iteration to obtain the pt_out holding when
875  exiting the loop */
876  pt_out = statement_to_points_to(b, pt_out_prev);
877  if(!expression_undefined_p(inc))
878  pt_out = expression_to_points_to(inc, pt_out, true);
879  if(!expression_undefined_p(c))
880  pt_out = condition_to_points_to(c, pt_out, false);
881  break;
882  }
883  else {
884  //ifdebug(1) {
885  if(true) {
886  pips_debug(1, "\n\nAt iteration i=%d:\n\n", i);
887  print_points_to_set("Loop points-to set pt_out_prev:\n",
888  points_to_graph_set(pt_out_prev));
889  print_points_to_set("Loop points-to set pt_out:\n",
890  points_to_graph_set(pt_out));
891  }
892  }
893  }
894 
895  if(!fix_point_p) {
896  print_points_to_set("Loop points-to set pt_out:\n", points_to_graph_set(pt_out));
897  print_points_to_set("Loop points-to set pt_out_prev:\n", points_to_graph_set(pt_out_prev));
898  pips_internal_error("Loop convergence not reached after %d iterations.\n", k+2);
899  }
900 
901  /* FI: I suppose that p[i] is replaced by p[*] and that MAY/MUST
902  information is changed accordingly. */
903  points_to_graph_set(pt_out) =
905 
906  pt_out = merge_points_to_graphs(pt_out, pt_out_skip);
907  }
908 
909  return pt_out;
910 }

References assign_pt_map, clear_pt_map, condition_to_points_to(), expression_to_points_to(), expression_undefined_p, full_copy_pt_map(), get_int_property(), init, merge_points_to_graphs(), new_pt_map, normalize_points_to_graph(), pips_debug, pips_internal_error, points_to_graph_bottom, points_to_graph_set, points_to_independent_store(), print_points_to_set(), set_equal_p(), and statement_to_points_to().

+ Here is the call graph for this function:

◆ points_to_context_statement_in()

pt_map points_to_context_statement_in ( void  )

Definition at line 127 of file statement.c.

128 {
130  return in;
131 }
points_to_graph pt_map

References stack_head(), and statement_points_to_context.

Referenced by user_call_to_points_to_interprocedural().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ points_to_context_statement_line_number()

int points_to_context_statement_line_number ( void  )

Definition at line 120 of file statement.c.

121 {
122  //statement s = stack_head(current_statement_points_to_context);
124  return statement_number(s);
125 }
statement get_current_statement_from_statement_global_stack(void)
Definition: static.c:344
#define statement_number(x)
Definition: ri.h:2452

References get_current_statement_from_statement_global_stack(), and statement_number.

Referenced by aliased_translation_p(), binary_intrinsic_call_to_points_to_sinks(), check_type_of_points_to_cells(), declaration_statement_to_points_to(), dereferencing_subscript_to_points_to(), equal_condition_to_points_to(), expression_to_points_to_cells(), filter_formal_context_according_to_actual_context(), freed_list_to_points_to(), freed_pointer_to_points_to(), internal_pointer_assignment_to_points_to(), intrinsic_call_to_points_to(), list_assignment_to_points_to(), memory_leak_to_more_memory_leaks(), new_filter_formal_context_according_to_actual_context(), non_equal_condition_to_points_to(), offset_cell(), offset_points_to_cell(), process_casted_sinks(), process_casted_sources(), reference_dereferencing_to_points_to(), reference_to_points_to_sinks(), source_to_sinks(), subscript_to_points_to_sinks(), subscripted_reference_to_points_to(), and user_call_to_points_to_interprocedural().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pop_statement_points_to_context()

pt_map pop_statement_points_to_context ( void  )

Definition at line 133 of file statement.c.

134 {
137 }
void * stack_pop(stack)
POPs one item from stack s.
Definition: stack.c:399

References current_statement_points_to_context, stack_pop(), and statement_points_to_context.

Referenced by statement_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ push_statement_points_to_context()

void push_statement_points_to_context ( statement  s,
pt_map  in 
)
Parameters
inn

Definition at line 98 of file statement.c.

99 {
102 }
void stack_push(void *, stack)
stack use
Definition: stack.c:373

References current_statement_points_to_context, stack_push(), and statement_points_to_context.

Referenced by statement_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reset_statement_points_to_context()

void reset_statement_points_to_context ( void  )

Definition at line 139 of file statement.c.

140 {
143 }
#define stack_undefined
Definition: newgen_stack.h:55
void stack_free(stack *)
type, bucket_size, policy
Definition: stack.c:292

References stack_free(), stack_undefined, and statement_points_to_context.

Referenced by generic_points_to_analysis().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sequence_to_points_to()

pt_map sequence_to_points_to ( sequence  seq,
pt_map  pt_in 
)
Parameters
seqeq
pt_int_in

Definition at line 436 of file statement.c.

437 {
438  pt_map pt_out = pt_in;
439  //bool store = true; // FI: management and use of store_p? Could be useful? How is it used?
440  // pt_out = points_to_sequence(seq, pt_in, store);
442  pt_out = statement_to_points_to(st, pt_out);
443  }
444 
445  return pt_out;
446 }
#define sequence_statements(x)
Definition: ri.h:2360

References FOREACH, sequence_statements, and statement_to_points_to().

Referenced by instruction_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ statement_points_to_context_defined_p()

◆ statement_to_points_to()

pt_map statement_to_points_to ( statement  s,
pt_map  pt_in 
)

See points_to_statement()

Process the declarations

Go down recursively, although it is currently useless since a declaration statement is a call to CONTINUE

Get the current version of pt_in, updated by the analysis of s.

Either pt_in or pt_out should be stored in the hash_table

But it might be smarter (or not) to require or not the storage.

Eliminate local information if you exit a block

The statement context is know unknown: it has been popped above. No precise error message in points_to_set_block_projection()

Because arc removals do not update the approximations of the remaining arcs, let's upgrade approximations before the information is passed. Useful for arithmetic02.

Really dangerous here: if pt_map "in" is empty, then pt_map "out" must be empty to...

FI: we have a problem to denote unreachable statement. To associate an empty set to them woud be a way to avoid problems when merging points-to along different control paths. But you might also wish to start with an empty set... And anyway, you can find declarations in dead code...

Parameters
pt_int_in

Definition at line 154 of file statement.c.

155 {
156  pips_assert("pt_in is consistent", consistent_pt_map_p(pt_in));
159  pt_map pt_out = new_pt_map();
160  pt_out = full_copy_pt_map(pt_in);
162 
163  if(points_to_graph_bottom(pt_in)) {
164  // The information about dead code must be propagated downwards
165  pt_out = instruction_to_points_to(i, pt_out);
166  pips_assert("The resulting points-to graph is bottom",
167  points_to_graph_bottom(pt_out));
168  }
169  else {
170 
171  init_heap_model(s);
172  // FI: it would be nice to stack the current statement in order to
173  // provide more helpful error messages
175 
176  if(declaration_statement_p(s)) {
177  /* Process the declarations */
178  pt_out = declaration_statement_to_points_to(s, pt_out);
179  pips_assert("pt_out is consistent", consistent_pt_map_p(pt_out));
180  /* Go down recursively, although it is currently useless since a
181  declaration statement is a call to CONTINUE */
182  pt_out = instruction_to_points_to(i, pt_out);
183  }
184  else {
185  pt_out = instruction_to_points_to(i, pt_out);
186  }
187 
188  pips_assert("pt_out is consistent", consistent_pt_map_p(pt_out));
189 
190  /* Get the current version of pt_in, updated by the analysis of s. */
192 
193  pips_assert("pt_in is consistent", consistent_pt_map_p(pt_in));
194 
196  }
197 
198  /* Either pt_in or pt_out should be stored in the hash_table
199  *
200  * But it might be smarter (or not) to require or not the storage.
201  */
202  // FI: currently, this is going to be redundant most of the time
203  pt_map pt_merged;
204  if(bound_pt_to_list_p(s)) {
205  points_to_list ptl_prev = load_pt_to_list(s);
206  list ptl_prev_l = gen_full_copy_list(points_to_list_list(ptl_prev));
207  pt_map pt_prev = new_pt_map();
208  pt_prev = graph_assign_list(pt_prev, ptl_prev_l);
209  gen_free_list(ptl_prev_l);
210  pt_merged = merge_points_to_graphs(pt_in, pt_prev);
211  }
212  else
213  pt_merged = pt_in;
214  fi_points_to_storage(pt_merged, s, true);
215 
216  /* Eliminate local information if you exit a block */
217  if(statement_sequence_p(s)) {
220  bool main_p = ms==s && entity_main_module_p(m);
221  bool body_p = ms==s;
223  /* The statement context is know unknown: it has been popped
224  above. No precise error message in
225  points_to_set_block_projection() */
227  points_to_graph_set(pt_out) =
228  points_to_set_block_projection(points_to_graph_set(pt_out), dl, main_p, body_p);
230  }
231 
232  /* Because arc removals do not update the approximations of the
233  remaining arcs, let's upgrade approximations before the
234  information is passed. Useful for arithmetic02. */
236 
237  /* Really dangerous here: if pt_map "in" is empty, then pt_map "out"
238  * must be empty to...
239  *
240  * FI: we have a problem to denote unreachable statement. To
241  * associate an empty set to them woud be a way to avoid problems
242  * when merging points-to along different control paths. But you
243  * might also wish to start with an empty set... And anyway, you can
244  * find declarations in dead code...
245  */
246  // FI: a temporary fix to the problem, to run experiments...
247  //if(empty_pt_map_p(pt_in) && !declaration_statement_p(s)
248  // && s!=get_current_module_statement())
249  // clear_pt_map(pt_out); // FI: memory leak?
250 
251  pips_assert("pt_out is consistent on exit", consistent_pt_map_p(pt_out));
252 
254 
255  return pt_out;
256 }
points_to_list load_pt_to_list(statement)
bool bound_pt_to_list_p(statement)
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
list gen_full_copy_list(list l)
Copy a list structure with element copy.
Definition: list.c:535
bool statement_sequence_p(statement s)
Statement classes induced from instruction type.
Definition: statement.c:335
bool declaration_statement_p(statement s)
Had to be optimized according to Beatrice Creusillet.
Definition: statement.c:224
void fi_points_to_storage(pt_map ptm, statement s, bool store)
Definition: passes.c:97
pt_map declaration_statement_to_points_to(statement s, pt_map pt_in)
See points_to_init()
Definition: statement.c:262
void push_statement_points_to_context(statement s, pt_map in)
Definition: statement.c:98
pt_map pop_statement_points_to_context(void)
Definition: statement.c:133
pt_map instruction_to_points_to(instruction i, pt_map pt_in)
See points_to_statement()
Definition: statement.c:370
void reset_heap_model(void)
Definition: sinks.c:1185
pt_map graph_assign_list(pt_map, list)
FI: I add functions dealing with points_to_graph variable, i.e.
set points_to_set_block_projection(set, list, bool, bool)
Remove from "pts" arcs based on at least one local entity in list "l" and preserve those based on sta...
void init_heap_model(statement)
Definition: sinks.c:1179
#define points_to_list_list(x)
bool entity_main_module_p(entity e)
Definition: entity.c:700
statement pop_statement_global_stack(void)
Definition: static.c:352
void push_statement_on_statement_global_stack(statement)
Definition: static.c:333
#define statement_instruction(x)
Definition: ri.h:2458

References bound_pt_to_list_p(), consistent_pt_map_p, declaration_statement_p(), declaration_statement_to_points_to(), entity_main_module_p(), fi_points_to_storage(), full_copy_pt_map(), gen_free_list(), gen_full_copy_list(), get_current_module_entity(), get_current_module_statement(), graph_assign_list(), init_heap_model(), instruction_to_points_to(), load_pt_to_list(), merge_points_to_graphs(), new_pt_map, pips_assert, points_to_graph_bottom, points_to_graph_set, points_to_list_list, points_to_set_block_projection(), pop_statement_global_stack(), pop_statement_points_to_context(), push_statement_on_statement_global_stack(), push_statement_points_to_context(), reset_heap_model(), statement_declarations, statement_instruction, statement_sequence_p(), and upgrade_approximations_in_points_to_set().

Referenced by any_loop_to_points_to(), control_to_points_to(), cyclic_graph_to_points_to(), generic_points_to_analysis(), new_any_loop_to_points_to(), new_points_to_unstructured(), sequence_to_points_to(), test_to_points_to(), and whileloop_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ test_to_points_to()

pt_map test_to_points_to ( test  t,
pt_map  pt_in 
)

Computing the points-to information after a test.

All the relationships are of type MAY, even if the same arc is defined, e.g. "if(c) p = &i; else p=&i;".

Might be refined later by using preconditions.

Make sure the condition is exploited, either because of side effects or simply because of dereferencements.

This cannot be done here because of side-effects.

FI: because the conditions must be evaluated for true and false?

condition's side effect and information are taked into account, e.g.:

"if(p=q)" or "if(*p++)" or "if(p)" which implies p->NULL in the else branch. FI: to be checked with test cases

We must use a common definition domain for both relations in order to obatin a really consistent points-to relation after the merge. This is similar to what is done in semantics for scalar preconditions.

Parameters
pt_int_in

Definition at line 496 of file statement.c.

497 {
498  pt_map pt_out = pt_map_undefined;
499 
500  //bool store = true;
501  // pt_out = points_to_test(t, pt_in, store);
502  // Translation of points_to_test
503  statement ts = test_true(t);
504  statement fs = test_false(t);
505  expression c = test_condition(t);
506  pt_map pt_t = pt_map_undefined;
507  pt_map pt_f = pt_map_undefined;
508 
509  /* Make sure the condition is exploited, either because of side
510  * effects or simply because of dereferencements.
511  *
512  * This cannot be done here because of side-effects.
513  *
514  * FI: because the conditions must be evaluated for true and false?
515  */
516  //pt_in = expression_to_points_to(c, pt_in);
517  //list el = expression_to_proper_constant_path_effects(c);
518  //if(!effects_write_p(el))
519  // pt_in = expression_to_points_to(c, pt_in, true);
520  //gen_free_list(el);
521 
522  // The side effects won't be taken into account when the condition
523  // is evaluated
524  pt_in = expression_to_points_to(c, pt_in, true);
525 
526  pt_map pt_in_t = full_copy_pt_map(pt_in);
527  pt_map pt_in_f = full_copy_pt_map(pt_in);
528 
529  /* condition's side effect and information are taked into account, e.g.:
530  *
531  * "if(p=q)" or "if(*p++)" or "if(p)" which implies p->NULL in the
532  * else branch. FI: to be checked with test cases */
533  if(!points_to_graph_bottom(pt_in_t)) // FI: we are in dead code
534  pt_in_t = condition_to_points_to(c, pt_in_t, true);
535  pt_t = statement_to_points_to(ts, pt_in_t);
536 
537  if(!points_to_graph_bottom(pt_in_f)) // FI: we are in dead code
538  pt_in_f = condition_to_points_to(c, pt_in_f, false);
539  pt_f = statement_to_points_to(fs, pt_in_f);
540 
541  pips_assert("pt_t is consistent", points_to_graph_consistent_p(pt_t));
542  pips_assert("pt_f is consistent", points_to_graph_consistent_p(pt_f));
543 
544  /* We must use a common definition domain for both relations in
545  order to obatin a really consistent points-to relation after the
546  merge. This is similar to what is done in semantics for scalar
547  preconditions. */
548  equalize_points_to_domains(pt_t, pt_f);
549 
550  pt_out = merge_points_to_graphs(pt_t, pt_f);
551 
552  pips_assert("pt_out is consistent", points_to_graph_consistent_p(pt_out));
553 
554  // FI: we should take care of pt_t and pt_f to avoid memory leaks
555  // In that specific case, clear_pt_map() and free_pt_map() should be ok
556 
557  pips_assert("pt_out is consistent", points_to_graph_consistent_p(pt_out));
558 
561  free_pt_map(pt_t), free_pt_map(pt_f);
562 
563  pips_assert("pt_out is consistent", points_to_graph_consistent_p(pt_out));
564 
565  return pt_out;
566 }
bool points_to_graph_consistent_p(points_to_graph p)
#define pt_map_undefined
#define free_pt_map(pt)
set set_clear(set)
Assign the empty set to s s := {}.
Definition: set.c:326
void equalize_points_to_domains(points_to_graph pt_t, points_to_graph pt_f)
Make sure that pt_t and pt_f have the same definition domain except if one of them is bottom.
Definition: statement.c:479
#define test_false(x)
Definition: ri.h:2837
#define test_true(x)
Definition: ri.h:2835
#define test_condition(x)
Definition: ri.h:2833

References condition_to_points_to(), equalize_points_to_domains(), expression_to_points_to(), free_pt_map, full_copy_pt_map(), merge_points_to_graphs(), pips_assert, points_to_graph_bottom, points_to_graph_consistent_p(), points_to_graph_set, pt_map_undefined, set_clear(), statement_to_points_to(), test_condition, test_false, and test_true.

Referenced by instruction_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ unstructured_to_points_to()

pt_map unstructured_to_points_to ( unstructured  u,
pt_map  pt_in 
)
Parameters
pt_int_in

Definition at line 958 of file statement.c.

959 {
960  pt_map pt_out = pt_in;
961 
962  pt_out = new_points_to_unstructured(u, pt_in, true);
963 
964  return pt_out;
965 }
pt_map new_points_to_unstructured(unstructured, pt_map, bool)

References new_points_to_unstructured().

Referenced by instruction_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ update_statement_points_to_context_with_arc()

void update_statement_points_to_context_with_arc ( points_to  pt)
Parameters
ptt

Definition at line 112 of file statement.c.

113 {
115  //add_arc_to_pt_map(pt, in);
117  pips_assert("in is consistent", consistent_pt_map_p(in));
118 }
pt_map update_points_to_graph_with_arc(points_to a, pt_map pt)
Instead of simply adding the new arc, make sure the consistency is not broken.
Definition: passes.c:183

References consistent_pt_map_p, pips_assert, stack_head(), statement_points_to_context, and update_points_to_graph_with_arc().

Referenced by update_points_to_context_with_arc().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ whileloop_to_points_to()

pt_map whileloop_to_points_to ( whileloop  wl,
pt_map  pt_in 
)

Execute the first iteration

Parameters
wll
pt_int_in

Definition at line 604 of file statement.c.

605 {
606  pt_map pt_out = pt_in;
607  statement b = whileloop_body(wl);
609 
610  //bool store = false;
612  //pt_out = points_to_whileloop(wl, pt_in, store);
613  //pt_out = expression_to_points_to(c, pt_out, false);
614  pt_out = expression_to_points_to(c, pt_out, true);
615  pt_out = any_loop_to_points_to(b,
617  c,
619  pt_in);
620  }
621  else {
622  // pt_out = points_to_do_whileloop(wl, pt_in, store);
623  /* Execute the first iteration */
624  pt_out = statement_to_points_to(b, pt_out);
625  pt_out = any_loop_to_points_to(b,
627  c,
629  pt_out);
630  }
631 
632  //statement ws = whileloop_body(wl);
633  //list dl = statement_declarations(ws);
634  // FI: to be improved
635  //if(declaration_statement_p(ws) && !ENDP(dl))
636  // pt_out = points_to_set_block_projection(pt_out, dl);
637 
639 
640  return pt_out;
641 }
#define whileloop_evaluation(x)
Definition: ri.h:3166
#define whileloop_body(x)
Definition: ri.h:3162
#define whileloop_condition(x)
Definition: ri.h:3160
#define evaluation_before_p(x)
Definition: ri.h:1159

References any_loop_to_points_to(), consistent_points_to_graph_p(), evaluation_before_p, expression_to_points_to(), expression_undefined, pips_assert, statement_to_points_to(), whileloop_body, whileloop_condition, and whileloop_evaluation.

Referenced by instruction_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ current_statement_points_to_context

stack current_statement_points_to_context = stack_undefined
static

◆ statement_points_to_context

stack statement_points_to_context = stack_undefined
static

The input points-to information of a statement is updated by the analysis of the statement because of the on-demand approach.

The formal context with its stubs is built onloy when necessary.

Definition at line 87 of file statement.c.

Referenced by add_arc_to_statement_points_to_context(), init_statement_points_to_context(), points_to_context_statement_in(), pop_statement_points_to_context(), push_statement_points_to_context(), reset_statement_points_to_context(), statement_points_to_context_defined_p(), and update_statement_points_to_context_with_arc().