PIPS
pointer_values.h File Reference
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  pv_context
 pv_context is a structure holding the methods to use during pointer values analyses More...
 
struct  pv_results
 pv_results is a structure holding the different results of an expression pointer values analysis More...
 

Macros

#define pips_debug_pv_results(level, message, pv_res)
 

Functions

bool pv_undefined_p (void)
 cproto-generated files More...
 
void reset_pv (void)
 
void error_reset_pv (void)
 
void set_pv (statement_cell_relations)
 
statement_cell_relations get_pv (void)
 
void init_pv (void)
 
void close_pv (void)
 
void store_pv (statement, cell_relations)
 
void update_pv (statement, cell_relations)
 
cell_relations load_pv (statement)
 
cell_relations delete_pv (statement)
 
bool bound_pv_p (statement)
 
void store_or_update_pv (statement, cell_relations)
 
bool gen_pv_undefined_p (void)
 
void reset_gen_pv (void)
 
void error_reset_gen_pv (void)
 
void set_gen_pv (statement_cell_relations)
 
statement_cell_relations get_gen_pv (void)
 
void init_gen_pv (void)
 
void close_gen_pv (void)
 
void store_gen_pv (statement, cell_relations)
 
void update_gen_pv (statement, cell_relations)
 
cell_relations load_gen_pv (statement)
 
cell_relations delete_gen_pv (statement)
 
bool bound_gen_pv_p (statement)
 
void store_or_update_gen_pv (statement, cell_relations)
 
bool kill_pv_undefined_p (void)
 
void reset_kill_pv (void)
 
void error_reset_kill_pv (void)
 
void set_kill_pv (statement_effects)
 
statement_effects get_kill_pv (void)
 
void init_kill_pv (void)
 
void close_kill_pv (void)
 
void store_kill_pv (statement, effects)
 
void update_kill_pv (statement, effects)
 
effects load_kill_pv (statement)
 
effects delete_kill_pv (statement)
 
bool bound_kill_pv_p (statement)
 
void store_or_update_kill_pv (statement, effects)
 
statement_cell_relations db_get_simple_pv (const char *)
 I don't know how to deal with these mappings if we have to analyse several modules at the same time when performing an interprocedural analysis. More...
 
void db_put_simple_pv (const char *, statement_cell_relations)
 
list db_get_in_simple_pv (const char *)
 
void db_put_in_simple_pv (const char *, list)
 
list db_get_out_simple_pv (const char *)
 
void db_put_out_simple_pv (const char *, list)
 
list db_get_initial_simple_pv (const char *)
 
void db_put_initial_simple_pv (const char *, list)
 
list db_get_program_simple_pv (void)
 
void db_put_program_simple_pv (list)
 
pv_context make_simple_pv_context (void)
 
void reset_pv_context (pv_context *)
 
void pv_context_statement_push (statement, pv_context *)
 
void pv_context_statement_pop (pv_context *)
 
statement pv_context_statement_head (pv_context *)
 
pv_results make_pv_results (void)
 
void free_pv_results_paths (pv_results *)
 
void print_pv_results (pv_results)
 
list make_anywhere_anywhere_pvs (void)
 
void range_to_post_pv (range, list, pv_results *, pv_context *)
 
void expression_to_post_pv (expression, list, pv_results *, pv_context *)
 
void single_pointer_assignment_to_post_pv (effect, list, list, bool, list, pv_results *, pv_context *)
 
void multiple_pointer_assignment_to_post_pv (effect, type, list, list, bool, list, pv_results *, pv_context *)
 
void assignment_to_post_pv (expression, bool, expression, bool, list, pv_results *, pv_context *)
 
bool simple_pointer_values (const string)
 interface to compute the simple pointer values of a given module More...
 
bool initial_simple_pointer_values (const string)
 
bool program_simple_pointer_values (const string)
 
list make_simple_pv_from_simple_effects (effect, effect, cell_interpretation, list)
 pointer_values_operators.c More...
 
list kill_pointer_values (list, list, pv_context *)
 eliminate the cells of l_kill from l_in More...
 
list kill_pointer_value (effect, list, pv_context *)
 eliminate the cell of eff_kill from l_in More...
 
cell_relation simple_pv_translate (cell_relation, bool, cell_relation)
 
list effect_find_equivalent_pointer_values (effect, list, cell_relation *, list *)
 find pointer_values in l_in which give (possible or exact) paths equivalent to eff. More...
 
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 More...
 
void pointer_values_remove_var (entity, bool, list, pv_results *, pv_context *)
 
cell_relation simple_pv_composition_with_transformer (cell_relation, transformer)
 
list pvs_composition_with_transformer (list, transformer, pv_context *)
 
list cell_relation_to_list (cell_relation)
 
list cell_relation_to_may_list (cell_relation)
 
list simple_pv_must_union (cell_relation, cell_relation)
 
list simple_pv_may_union (cell_relation, cell_relation)
 
bool pvs_union_combinable_p (cell_relation, cell_relation)
 
list simple_pvs_must_union (list, list)
 
list simple_pvs_may_union (list, list)
 
bool simple_pvs_syntactically_equal_p (list, list)
 
void intrinsic_to_post_pv (entity, list, list, pv_results *, pv_context *)
 pointer_values_intrinsics.c More...
 
text text_pv (entity, int, statement)
 prettyprint.c More...
 
bool generic_print_code_pv (char *, pv_context *)
 
bool print_code_simple_pointer_values (char *)
 
void generic_print_code_gen_kill_pv (char *)
 
bool print_code_simple_gen_kill_pointer_values (char *)
 

Macro Definition Documentation

◆ pips_debug_pv_results

#define pips_debug_pv_results (   level,
  message,
  pv_res 
)
Value:
print_pv_results(pv_res);}
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define level
#define ifdebug(n)
Definition: sg.c:47

Definition at line 91 of file pointer_values.h.

Function Documentation

◆ assignment_to_post_pv()

void assignment_to_post_pv ( expression  lhs,
bool  may_lhs_p,
expression  rhs,
bool  declaration_p,
list  l_in,
pv_results pv_res,
pv_context ctxt 
)

first convert the rhs and lhs into memory paths, rhs is evaluated first

this is done even if this is a non-pointer assignment, becasue there maybe side effects on alising hidden in sub-expressions, function calls...

we should test here that lhs_pv_res.result_paths has only one element. well is it correct? can a relational operator expression be a lhs ?

l_gen = NIL; l_kill = NIL;

simple case first: lhs is a pointer

hidden pointer assignments

if (type_variable_p(lhs_type)

Parameters
lhshs
may_lhs_pay_lhs_p
rhshs
declaration_peclaration_p
l_in_in
pv_resv_res
ctxttxt

Definition at line 1582 of file pointer_values_analyses.c.

1585 {
1586  list l_in_cur = NIL;
1587  effect lhs_eff = effect_undefined;
1588 
1589  pips_debug(1, "begin with may_lhs_p = %s and declaration_p = %s\n", bool_to_string(may_lhs_p), bool_to_string(declaration_p));
1590  pips_debug_pvs(2, "input pointer values:\n", l_in);
1591  type lhs_type = expression_to_type(lhs);
1592 
1593  /* first convert the rhs and lhs into memory paths, rhs is evaluated first */
1594  /* this is done even if this is a non-pointer assignment, becasue there
1595  maybe side effects on alising hidden in sub-expressions, function calls...
1596  */
1597  pv_results lhs_pv_res = make_pv_results();
1598  pv_results rhs_pv_res = make_pv_results();
1599 
1600  expression_to_post_pv(rhs, l_in, &rhs_pv_res, ctxt);
1601  list l_rhs_eff = rhs_pv_res.result_paths;
1602  list l_rhs_kind = rhs_pv_res.result_paths_interpretations;
1603  l_in_cur = rhs_pv_res.l_out;
1604 
1605  expression_to_post_pv(lhs, l_in_cur, &lhs_pv_res, ctxt);
1606  l_in_cur = lhs_pv_res.l_out;
1607  /* we should test here that lhs_pv_res.result_paths has only one element.
1608  well is it correct? can a relational operator expression be a lhs ?
1609  */
1610  lhs_eff = EFFECT(CAR(lhs_pv_res.result_paths));
1611  if (may_lhs_p) effect_to_may_effect(lhs_eff);
1612  pv_res->result_paths = CONS(EFFECT, copy_effect(lhs_eff), NIL);
1615 
1617  {
1618  pips_debug(2, "non-pointer assignment\n");
1619  /* l_gen = NIL; l_kill = NIL; */
1620  pv_res->l_out = l_in_cur;
1621  }
1622  else
1623  {
1624  if(type_variable_p(lhs_type))
1625  {
1626  if (pointer_type_p(lhs_type)) /* simple case first: lhs is a pointer */
1627  {
1628  single_pointer_assignment_to_post_pv(lhs_eff, l_rhs_eff,
1629  l_rhs_kind,
1630  declaration_p, l_in_cur,
1631  pv_res, ctxt);
1632  }
1633  else /* hidden pointer assignments */
1634  {
1635  multiple_pointer_assignment_to_post_pv(lhs_eff, lhs_type, l_rhs_eff,
1636  l_rhs_kind,
1637  declaration_p, l_in_cur,
1638  pv_res, ctxt);
1639  }
1640  } /* if (type_variable_p(lhs_type) */
1641  else if(type_functional_p(lhs_type))
1642  {
1643  pips_internal_error("not yet implemented");
1644  }
1645  else
1646  pips_internal_error("unexpected_type");
1647  }
1648 
1649 
1650  free_pv_results_paths(&lhs_pv_res);
1651  free_pv_results_paths(&rhs_pv_res);
1652 
1653  pips_debug_pv_results(1, "end with pv_res =\n", *pv_res);
1654  return;
1655 }
cell_interpretation make_cell_interpretation_value_of(void)
Definition: effects.c:237
effect copy_effect(effect p)
EFFECT.
Definition: effects.c:448
void effect_to_may_effect(effect)
#define pips_debug_pvs(level, message, l_pv)
#define effect_undefined
Definition: effects.h:614
#define CELL_INTERPRETATION(x)
CELL_INTERPRETATION.
Definition: effects.h:375
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define pips_internal_error
Definition: misc-local.h:149
string bool_to_string(bool)
Definition: string.c:243
#define pips_debug_pv_results(level, message, pv_res)
pv_results make_pv_results()
void expression_to_post_pv(expression exp, list l_in, pv_results *pv_res, pv_context *ctxt)
void free_pv_results_paths(pv_results *pv_res)
void single_pointer_assignment_to_post_pv(effect lhs_eff, list l_rhs_eff, list l_rhs_kind, bool declaration_p, list l_in, pv_results *pv_res, pv_context *ctxt)
void multiple_pointer_assignment_to_post_pv(effect lhs_base_eff, type lhs_type, list l_rhs_base_eff, list l_rhs_base_kind, bool declaration_p, list l_in, pv_results *pv_res, pv_context *ctxt)
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 type_fundamental_basic_p(type)
Definition: type.c:2930
bool basic_concrete_type_leads_to_pointer_p(type)
returns true when the input type successors may be pointers
Definition: type.c:3699
bool pointer_type_p(type)
Check for scalar pointers.
Definition: type.c:2993
#define type_functional_p(x)
Definition: ri.h:2950
#define type_variable_p(x)
Definition: ri.h:2947
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
pv_results is a structure holding the different results of an expression pointer values analysis
list result_paths_interpretations
resulting pointer path of the expression evaluation
list result_paths
resulting pointer_values

References basic_concrete_type_leads_to_pointer_p(), bool_to_string(), CAR, CELL_INTERPRETATION, CONS, copy_effect(), EFFECT, effect_to_may_effect(), effect_undefined, expression_to_post_pv(), expression_to_type(), free_pv_results_paths(), pv_results::l_out, make_cell_interpretation_value_of(), make_pv_results(), multiple_pointer_assignment_to_post_pv(), NIL, pips_debug, pips_debug_pv_results, pips_debug_pvs, pips_internal_error, pointer_type_p(), pv_results::result_paths, pv_results::result_paths_interpretations, single_pointer_assignment_to_post_pv(), type_functional_p, type_fundamental_basic_p(), and type_variable_p.

Referenced by assignment_intrinsic_to_post_pv(), declaration_to_post_pv(), and pointer_values_remove_var().

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

◆ bound_gen_pv_p()

bool bound_gen_pv_p ( statement  )

◆ bound_kill_pv_p()

bool bound_kill_pv_p ( statement  )

◆ bound_pv_p()

bool bound_pv_p ( statement  )

Referenced by sequence_to_post_pv(), and statement_to_post_pv().

+ Here is the caller graph for this function:

◆ cell_relation_to_list()

list cell_relation_to_list ( cell_relation  cr)
Parameters
crr

Definition at line 800 of file pointer_values_operators.c.

801 {
802  return CONS(CELL_RELATION, cr, NIL);
803 }
#define CELL_RELATION(x)
CELL_RELATION.
Definition: effects.h:479

References CELL_RELATION, CONS, and NIL.

Referenced by simple_pvs_must_union().

+ Here is the caller graph for this function:

◆ cell_relation_to_may_list()

list cell_relation_to_may_list ( cell_relation  cr)
Parameters
crr

Definition at line 805 of file pointer_values_operators.c.

806 {
808  return CONS(CELL_RELATION, cr, NIL);
809 }
#define cell_relation_approximation_tag(cr)
@ is_approximation_may
Definition: effects.h:341

References CELL_RELATION, cell_relation_approximation_tag, CONS, is_approximation_may, and NIL.

Referenced by simple_pvs_may_union().

+ Here is the caller graph for this function:

◆ close_gen_pv()

void close_gen_pv ( void  )

◆ close_kill_pv()

void close_kill_pv ( void  )

◆ close_pv()

void close_pv ( void  )

◆ db_get_in_simple_pv()

list db_get_in_simple_pv ( const char *  module_name)
Parameters
module_nameodule_name

Definition at line 73 of file pointer_values_analyses.c.

74 {
75  return (list) cell_relations_list((cell_relations) db_get_memory_resource(DBR_IN_SIMPLE_POINTER_VALUES, module_name, true));
76 }
#define cell_relations_list(x)
Definition: effects.h:549
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
Definition: database.c:755

References cell_relations_list, db_get_memory_resource(), and module_name().

Referenced by make_simple_pv_context().

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

◆ db_get_initial_simple_pv()

list db_get_initial_simple_pv ( const char *  module_name)
Parameters
module_nameodule_name

Definition at line 93 of file pointer_values_analyses.c.

94 {
95  return cell_relations_list((cell_relations) db_get_memory_resource(DBR_INITIAL_SIMPLE_POINTER_VALUES, module_name, true));
96 }

References cell_relations_list, db_get_memory_resource(), and module_name().

Referenced by make_simple_pv_context().

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

◆ db_get_out_simple_pv()

list db_get_out_simple_pv ( const char *  module_name)
Parameters
module_nameodule_name

Definition at line 83 of file pointer_values_analyses.c.

84 {
85  return cell_relations_list((cell_relations) db_get_memory_resource(DBR_OUT_SIMPLE_POINTER_VALUES, module_name, true));
86 }

References cell_relations_list, db_get_memory_resource(), and module_name().

Referenced by make_simple_pv_context().

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

◆ db_get_program_simple_pv()

list db_get_program_simple_pv ( void  )

Definition at line 103 of file pointer_values_analyses.c.

104 {
105  return cell_relations_list((cell_relations) db_get_memory_resource(DBR_PROGRAM_SIMPLE_POINTER_VALUES, "", true));
106 }

References cell_relations_list, and db_get_memory_resource().

Referenced by make_simple_pv_context().

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

◆ db_get_simple_pv()

statement_cell_relations db_get_simple_pv ( const char *  module_name)

I don't know how to deal with these mappings if we have to analyse several modules at the same time when performing an interprocedural analysis.

We may need a stack of mappings, or a global mapping for the whole program, and a temporary mapping to store the resources one module at a time

Parameters
module_nameodule_name

Definition at line 63 of file pointer_values_analyses.c.

64 {
65  return (statement_cell_relations) db_get_memory_resource(DBR_SIMPLE_POINTER_VALUES, module_name, true);
66 }

References db_get_memory_resource(), and module_name().

Referenced by make_simple_pv_context().

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

◆ db_put_in_simple_pv()

void db_put_in_simple_pv ( const char *  module_name,
list  l_pv 
)
Parameters
module_nameodule_name
l_pv_pv

Definition at line 78 of file pointer_values_analyses.c.

79 {
80  DB_PUT_MEMORY_RESOURCE(DBR_IN_SIMPLE_POINTER_VALUES, module_name, (char*) make_cell_relations(l_pv));
81 }
cell_relations make_cell_relations(list a)
Definition: effects.c:383
#define DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
Definition: pipsdbm-local.h:66

References DB_PUT_MEMORY_RESOURCE, make_cell_relations(), and module_name().

Referenced by make_simple_pv_context().

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

◆ db_put_initial_simple_pv()

void db_put_initial_simple_pv ( const char *  module_name,
list  l_pv 
)
Parameters
module_nameodule_name
l_pv_pv

Definition at line 98 of file pointer_values_analyses.c.

99 {
100  DB_PUT_MEMORY_RESOURCE(DBR_INITIAL_SIMPLE_POINTER_VALUES, module_name, (char*) make_cell_relations(l_pv));
101 }

References DB_PUT_MEMORY_RESOURCE, make_cell_relations(), and module_name().

Referenced by make_simple_pv_context().

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

◆ db_put_out_simple_pv()

void db_put_out_simple_pv ( const char *  module_name,
list  l_pv 
)
Parameters
module_nameodule_name
l_pv_pv

Definition at line 88 of file pointer_values_analyses.c.

89 {
90  DB_PUT_MEMORY_RESOURCE(DBR_OUT_SIMPLE_POINTER_VALUES, module_name, (char*) make_cell_relations(l_pv));
91 }

References DB_PUT_MEMORY_RESOURCE, make_cell_relations(), and module_name().

Referenced by make_simple_pv_context().

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

◆ db_put_program_simple_pv()

void db_put_program_simple_pv ( list  l_pv)
Parameters
l_pv_pv

Definition at line 108 of file pointer_values_analyses.c.

109 {
110  DB_PUT_MEMORY_RESOURCE(DBR_PROGRAM_SIMPLE_POINTER_VALUES, "", (char*) make_cell_relations(l_pv));
111 }

References DB_PUT_MEMORY_RESOURCE, and make_cell_relations().

Referenced by make_simple_pv_context().

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

◆ db_put_simple_pv()

void db_put_simple_pv ( const char *  module_name,
statement_cell_relations  scr 
)
Parameters
module_nameodule_name
scrcr

Definition at line 68 of file pointer_values_analyses.c.

69 {
70  DB_PUT_MEMORY_RESOURCE(DBR_SIMPLE_POINTER_VALUES, module_name, (char*) scr);
71 }

References DB_PUT_MEMORY_RESOURCE, and module_name().

Referenced by make_simple_pv_context().

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

◆ delete_gen_pv()

cell_relations delete_gen_pv ( statement  )

◆ delete_kill_pv()

effects delete_kill_pv ( statement  )

◆ delete_pv()

cell_relations delete_pv ( statement  )

◆ effect_find_aliased_paths_with_pointer_values()

list effect_find_aliased_paths_with_pointer_values ( effect  eff,
list  l_pv,
pv_context ctxt 
)

find all paths equivalent to eff cell in l_pv by performing a transitive closure

Parameters
effis the input effect
l_pvis the list of current pointer_values relations
ctxtis the pv analysis context
Returns
a list of effects whose cells are equivalent to eff_kill cell according to l_pv. Their approximation does not depend on the approximation of the input effect, but only on the exactness of the finding process.
Parameters
effff
l_pv_pv
ctxttxt

Definition at line 678 of file pointer_values_operators.c.

679 {
680  bool exact_p;
681  // for gcc
682  pips_assert("true", ctxt==ctxt);
690 }
list generic_effect_find_aliases_with_simple_pointer_values(effect, list, bool *, transformer, bool(*)(cell, descriptor, cell, descriptor, transformer, bool, bool *), void(*)(cell, descriptor, cell, descriptor, int, cell *, descriptor *, bool *), void(*)(cell, descriptor, cell, descriptor, int, cell *, descriptor *, bool *), bool(*)(cell, descriptor, cell, descriptor, bool *), bool(*)(cell, descriptor, cell, descriptor, bool *), void(*)(cell, cell *, descriptor *))
Definition: eval.c:673
bool simple_cells_inclusion_p(cell c1, __attribute__((__unused__)) descriptor d1, cell c2, __attribute__((__unused__)) descriptor d2, bool *exact_p)
Inclusion test :
bool simple_cells_intersection_p(cell c1, descriptor __attribute__((__unused__)) d1, cell c2, descriptor __attribute__((__unused__)) d2, bool *exact_p)
bool simple_cell_preceding_p(cell, descriptor, cell, descriptor, transformer, bool, bool *)
Definition: eval.c:119
void simple_cell_with_value_of_cell_translation(cell, descriptor, cell, descriptor, int, cell *, descriptor *, bool *)
void simple_cell_to_simple_cell_conversion(cell, cell *, descriptor *)
Definition: eval.c:154
void simple_cell_with_address_of_cell_translation(cell, descriptor, cell, descriptor, int, cell *, descriptor *, bool *)
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define transformer_undefined
Definition: ri.h:2847

References generic_effect_find_aliases_with_simple_pointer_values(), pips_assert, simple_cell_preceding_p(), simple_cell_to_simple_cell_conversion(), simple_cell_with_address_of_cell_translation(), simple_cell_with_value_of_cell_translation(), simple_cells_inclusion_p(), simple_cells_intersection_p(), and transformer_undefined.

Referenced by simple_effect_to_constant_path_effects_with_pointer_values(), and single_pointer_assignment_to_post_pv().

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

◆ effect_find_equivalent_pointer_values()

list effect_find_equivalent_pointer_values ( effect  eff,
list  l_in,
cell_relation exact_aliased_pv,
list l_in_remnants 
)

find pointer_values in l_in which give (possible or exact) paths equivalent to eff.

Parameters
effis the considered input path.
l_inis the input pointer values list.
exact_aliased_pvgives an exact equivalent path found in l_in if it exists.
l_in_remnantscontains the elemnts of l_in which are neither exact_aliased_pv nor in the returned list.
Returns
a list of elements of l_in which give (possible or exact) paths equivalent to eff, excluding exact_aliased_pv if one exact equivalent path can be found in l_in.
Parameters
effff
l_in_in
exact_aliased_pvxact_aliased_pv
l_in_remnants_in_remnants

Definition at line 658 of file pointer_values_operators.c.

661 {
662  return generic_effect_find_equivalent_simple_pointer_values(eff, l_in, exact_aliased_pv, l_in_remnants,
666 }
list generic_effect_find_equivalent_simple_pointer_values(effect, list, cell_relation *, list *, bool(*)(cell, descriptor, cell, descriptor, bool *), bool(*)(cell, descriptor, cell, descriptor, bool *), void(*)(cell, cell *, descriptor *))
find pointer_values in l_in which give (possible or exact) paths equivalent to eff.
Definition: eval.c:506

References generic_effect_find_equivalent_simple_pointer_values(), simple_cell_to_simple_cell_conversion(), simple_cells_inclusion_p(), and simple_cells_intersection_p().

Referenced by free_to_post_pv(), kill_pointer_value(), and make_simple_pv_from_simple_effects().

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

◆ error_reset_gen_pv()

void error_reset_gen_pv ( void  )

◆ error_reset_kill_pv()

void error_reset_kill_pv ( void  )

◆ error_reset_pv()

void error_reset_pv ( void  )

◆ expression_to_post_pv()

void expression_to_post_pv ( expression  exp,
list  l_in,
pv_results pv_res,
pv_context ctxt 
)

we assume no effects on aliases due to subscripts evaluations for the moment

we assume no effects on aliases due to sizeof argument expression for the moment

aborts if there are calls in subscript expressions

free the spine

we assume no effects on aliases due to subscripts evaluations for the moment

Parameters
expxp
l_in_in
pv_resv_res
ctxttxt

Definition at line 930 of file pointer_values_analyses.c.

931 {
933  {
934  pips_debug(1, "begin for undefined expression, returning undefined pointer_value\n");
935  pv_res->l_out = l_in;
942  }
943  else
944  {
945  pips_debug(1, "begin for expression : %s\n",
947 
948  syntax exp_syntax = expression_syntax(exp);
949 
950  switch(syntax_tag(exp_syntax))
951  {
952  case is_syntax_reference:
953  pips_debug(5, "reference case\n");
954  reference exp_ref = syntax_reference(exp_syntax);
955  if (same_string_p(entity_local_name(reference_variable(exp_ref)), "NULL"))
956  {
963  NIL);
964  }
965  else
966  {
967  // functions that can be pointed by reference_to_effect_func:
968  // reference_to_simple_effect
969  // reference_to_convex_region
970  // reference_to_reference_effect
971  pv_res->result_paths = CONS(EFFECT,
973  (copy_reference(exp_ref),
975  false), NIL);
978  NIL);
979  }
980  /* we assume no effects on aliases due to subscripts evaluations for the moment */
981  pv_res->l_out = l_in;
982  break;
983  case is_syntax_range:
984  pips_internal_error("not yet implemented");
985  break;
986  case is_syntax_call:
987  {
988  call_to_post_pv(syntax_call(exp_syntax), l_in, pv_res, ctxt);
989  break;
990  }
991  case is_syntax_cast:
992  {
994  l_in, pv_res, ctxt);
995  pips_debug(5, "cast case\n");
996  break;
997  }
999  {
1000  /* we assume no effects on aliases due to sizeof argument expression
1001  * for the moment */
1002  pv_res->l_out = l_in;
1003  break;
1004  }
1005  case is_syntax_subscript:
1006  {
1007  pips_debug(5, "subscript case\n");
1008  /* aborts if there are calls in subscript expressions */
1009  list l_eff = NIL;
1011  gen_full_free_list(l_tmp);
1012  FOREACH(EFFECT, eff, l_eff)
1013  {
1014  pv_res->result_paths = CONS(EFFECT, eff, NIL);
1017  NIL);
1018  }
1019  gen_free_list(l_eff); /* free the spine */
1020  /* we assume no effects on aliases due to subscripts evaluations for the moment */
1021  pv_res->l_out = l_in;
1022  break;
1023  }
1024  case is_syntax_application:
1025  pips_internal_error("not yet implemented");
1026  break;
1027  case is_syntax_va_arg:
1028  {
1029  pips_internal_error("not yet implemented");
1030  break;
1031  }
1032  default:
1033  pips_internal_error("unexpected tag %d", syntax_tag(exp_syntax));
1034  break;
1035  }
1036  }
1037 
1038  pips_debug_pv_results(1, "end with pv_results =\n", *pv_res);
1039  pips_debug(1, "end\n");
1040  return;
1041 }
approximation make_approximation_exact(void)
Definition: effects.c:185
effect make_effect(cell a1, action a2, approximation a3, descriptor a4)
Definition: effects.c:484
descriptor make_descriptor_none(void)
Definition: effects.c:442
reference copy_reference(reference p)
REFERENCE.
Definition: ri.c:2047
list generic_proper_effects_of_complex_address_expression(expression, list *, int)
effect(* reference_to_effect_func)(reference, action, bool)
action make_action_write_memory(void)
To ease the extension of action with action_kind.
Definition: effects.c:1011
cell make_null_pointer_value_cell(void)
cell make_undefined_pointer_value_cell(void)
action make_action_read_memory(void)
Definition: effects.c:1017
void gen_full_free_list(list l)
Definition: genClib.c:1023
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 same_string_p(s1, s2)
static void call_to_post_pv(call c, list l_in, pv_results *pv_res, pv_context *ctxt)
string expression_to_string(expression e)
Definition: expression.c:77
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
#define syntax_reference(x)
Definition: ri.h:2730
#define syntax_tag(x)
Definition: ri.h:2727
#define reference_variable(x)
Definition: ri.h:2326
#define syntax_cast(x)
Definition: ri.h:2739
@ is_syntax_range
Definition: ri.h:2692
@ is_syntax_application
Definition: ri.h:2697
@ is_syntax_cast
Definition: ri.h:2694
@ is_syntax_call
Definition: ri.h:2693
@ is_syntax_va_arg
Definition: ri.h:2698
@ is_syntax_reference
Definition: ri.h:2691
@ is_syntax_sizeofexpression
Definition: ri.h:2695
@ is_syntax_subscript
Definition: ri.h:2696
#define cast_expression(x)
Definition: ri.h:747
#define syntax_call(x)
Definition: ri.h:2736
#define expression_undefined_p(x)
Definition: ri.h:1224
#define expression_syntax(x)
Definition: ri.h:1247
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207

References call_to_post_pv(), cast_expression, CELL_INTERPRETATION, CONS, copy_reference(), EFFECT, entity_local_name(), exp, expression_syntax, expression_to_post_pv(), expression_to_string(), expression_undefined_p, FOREACH, gen_free_list(), gen_full_free_list(), generic_proper_effects_of_complex_address_expression(), is_syntax_application, is_syntax_call, is_syntax_cast, is_syntax_range, is_syntax_reference, is_syntax_sizeofexpression, is_syntax_subscript, is_syntax_va_arg, pv_results::l_out, make_action_read_memory(), make_action_write_memory(), make_approximation_exact(), make_cell_interpretation_value_of(), make_descriptor_none(), make_effect(), make_null_pointer_value_cell(), make_undefined_pointer_value_cell(), NIL, pips_debug, pips_debug_pv_results, pips_internal_error, reference_to_effect_func, reference_variable, pv_results::result_paths, pv_results::result_paths_interpretations, same_string_p, syntax_call, syntax_cast, syntax_reference, and syntax_tag.

Referenced by address_of_to_post_pv(), assignment_to_post_pv(), binary_arithmetic_operator_to_post_pv(), c_return_to_post_pv(), conditional_operator_to_post_pv(), default_intrinsic_to_post_pv(), dereferencing_to_post_pv(), expression_to_post_pv(), external_call_to_post_pv(), field_to_post_pv(), forloop_to_post_pv(), heap_intrinsic_to_post_pv(), instruction_to_post_pv(), logical_operator_to_post_pv(), point_to_to_post_pv(), range_to_post_pv(), safe_intrinsic_to_post_pv(), test_to_post_pv(), unary_arithmetic_operator_to_post_pv(), update_operator_to_post_pv(), and whileloop_to_post_pv().

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

◆ free_pv_results_paths()

◆ gen_pv_undefined_p()

bool gen_pv_undefined_p ( void  )

◆ generic_print_code_gen_kill_pv()

void generic_print_code_gen_kill_pv ( char *  module_name)
Parameters
module_nameodule_name

Definition at line 90 of file prettyprint.c.

91 {
93 }

References module_name(), and pips_assert.

Referenced by print_code_simple_gen_kill_pointer_values().

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

◆ generic_print_code_pv()

bool generic_print_code_pv ( char *  module_name,
pv_context ctxt 
)
Parameters
module_nameodule_name
ctxttxt

Definition at line 53 of file prettyprint.c.

54 {
55  bool success;
56 
58  db_get_memory_resource(DBR_CODE, module_name, true));
60 
62 
63  list l_in = (*ctxt->db_get_in_pv_func)(module_name);
64  list l_out = (*ctxt->db_get_in_pv_func)(module_name);
65 
67  text t = make_text(NIL);
68  MERGE_TEXTS(t, text_pointer_values(l_in, "IN Pointer values:"));
69  MERGE_TEXTS(t, text_pointer_values(l_out, "OUT Pointer values:"));
72  success = make_text_resource_and_free(module_name, DBR_PRINTED_FILE, ".pv", t);
74 
77  reset_pv();
78  return success;
79 }
text make_text(list a)
Definition: text.c:107
text text_pointer_values(list lpv, string header)
Definition: prettyprint.c:571
bool success
Definition: gpips-local.h:59
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
text text_pv(entity __attribute__((unused)) module, int __attribute__((unused)) margin, statement s)
Definition: prettyprint.c:46
void set_pv(statement_cell_relations)
void reset_pv(void)
void close_prettyprint()
because some prettyprint functions may be used for debug, so the last hook set by somebody may have s...
Definition: misc.c:242
void init_prettyprint(text(*hook)(entity, int, statement))
checks that the prettyprint hook was actually reset...
Definition: misc.c:231
text text_module(entity, statement)
bool make_text_resource_and_free(const char *, const char *, const char *, text)
Definition: print.c:82
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
list(* db_get_in_pv_func)(const char *)
statement_cell_relations(* db_get_pv_func)(const char *)
set to true for an initial module analysis
#define MERGE_TEXTS(r, t)

References close_prettyprint(), pv_context::db_get_in_pv_func, db_get_memory_resource(), pv_context::db_get_pv_func, get_current_module_entity(), get_current_module_statement(), init_prettyprint(), make_text(), make_text_resource_and_free(), MERGE_TEXTS, module_name(), module_name_to_entity(), NIL, reset_current_module_entity(), reset_current_module_statement(), reset_pv(), set_current_module_entity(), set_current_module_statement(), set_pv(), text_module(), text_pointer_values(), and text_pv().

Referenced by print_code_simple_pointer_values().

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

◆ get_gen_pv()

statement_cell_relations get_gen_pv ( void  )

◆ get_kill_pv()

statement_effects get_kill_pv ( void  )

◆ get_pv()

statement_cell_relations get_pv ( void  )

Referenced by generic_module_pointer_values().

+ Here is the caller graph for this function:

◆ init_gen_pv()

void init_gen_pv ( void  )

◆ init_kill_pv()

void init_kill_pv ( void  )

◆ init_pv()

void init_pv ( void  )

Referenced by generic_module_initial_pointer_values(), and generic_module_pointer_values().

+ Here is the caller graph for this function:

◆ initial_simple_pointer_values()

bool initial_simple_pointer_values ( const  string)
Parameters
stringodule_name

Definition at line 1925 of file pointer_values_analyses.c.

1926 {
1928  ctxt.initial_pointer_values_p = true;
1931  reset_pv_context(&ctxt);
1933  return(true);
1934 }
void generic_effects_reset_all_methods(void)
void set_methods_for_simple_effects(void)
static void generic_module_initial_pointer_values(char *module_name, pv_context *ctxt)
pv_context make_simple_pv_context()
void reset_pv_context(pv_context *p_ctxt)
pv_context is a structure holding the methods to use during pointer values analyses
bool initial_pointer_values_p
ANALYSIS CONTROL.

References generic_effects_reset_all_methods(), generic_module_initial_pointer_values(), pv_context::initial_pointer_values_p, make_simple_pv_context(), module_name(), reset_pv_context(), and set_methods_for_simple_effects().

+ Here is the call graph for this function:

◆ intrinsic_to_post_pv()

void intrinsic_to_post_pv ( entity  func,
list  func_args,
list  l_in,
pv_results pv_res,
pv_context ctxt 
)

pointer_values_intrinsics.c

Parameters
funcunc
func_argsunc_args
l_in_in
pv_resv_res
ctxttxt

Definition at line 1969 of file pointer_values_intrinsics.c.

1971 {
1972  const char* func_name = entity_local_name(func);
1973  pips_debug(1, "begin for %s\n", func_name);
1974 
1976 
1977  while (pid->name != NULL)
1978  {
1979  if (strcmp(pid->name, func_name) == 0)
1980  {
1981  (*(pid->to_post_pv_function))(func, func_args, l_in, pv_res, ctxt);
1982  pips_debug_pv_results(2, "resulting pv_res:", *pv_res);
1983  pips_debug(1, "end\n");
1984  return;
1985  }
1986  pid += 1;
1987  }
1988 
1989  pips_internal_error("unknown intrinsic %s", func_name);
1990  pips_debug(1, "end\n");
1991  return;
1992 }
static IntrinsicToPostPVDescriptor IntrinsicToPostPVDescriptorTable[]
The following data structure describes an intrinsic function: its name and its arity and its type,...

References entity_local_name(), IntrinsicToPostPVDescriptorTable, IntrinsicDescriptor::name, pips_debug, pips_debug_pv_results, pips_internal_error, and IntrinsicDescriptor::to_post_pv_function.

Referenced by call_to_post_pv().

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

◆ kill_pointer_value()

list kill_pointer_value ( effect  eff_kill,
list  l_in,
pv_context ctxt 
)

eliminate the cell of eff_kill from l_in

Parameters
eff_killis the effect describing the cell to be killed
l_inis the input list of pointer_values.
ctxtis a pointer on the pointer values analysis contex.
Returns
a list of newly allocated pointer_values Not yet very generic: either should be made generic or a specific version made for convex pointer values/effects.

all pointers may be killed

eff_kill characteristics

using old_values, take into account the impact of eff_kill on l_in pointer values second cells which must be expressed in terms of unchanged paths.

should we translate the first or the second pv_in cell

must it be translated ?

pv_in first cell characteristics

pv_in second cell characteristics

pointer value relation is still valid

This should be made generic

we must translate ref_in using the old_values

if there is an exact candidate, it is ranked first and we can use it

generate a new pv for each element of old_values

FOREACH(CELL_RELATION, old_pv, l_old_values)

else branch of if (exact_first_pv)

if (to_be_translated)

FOREACH (CELL_RELATION, pv_in, l_remnants)

Second, take into account the impact of eff_kill on l_old_values relations. We only have to keep those which are not completely killed by kill_eff, and set their approximation to may (this is also true for exact_old_pv)

first use exact_old_pv to translate exact old_values

Then the other old_values

we already know that there may be a non-empty intersection with cell_kill

some more work is necessary

some more precise work could be done here by computing the difference between the pv_old first cell and cell_kill. I don't know if it would be really useful. So let us avoid too complex things for the moment.

some more precise work could be done here by computing the difference between the pv_old first cell and cell_kill. I don't know if it would be really useful. So let us avoid too complex things for the moment.

Parameters
eff_killff_kill
l_inof cell_relations
ctxttxt

Definition at line 193 of file pointer_values_operators.c.

195 {
196  list l_out = NIL;
197 
198  pips_debug_pvs(1, "begin with l_in:", l_in);
199  pips_debug_effect(1, "and eff_kill:", eff_kill);
200 
201 
202  if (anywhere_effect_p(eff_kill))
203  {
204  /* all pointers may be killed */
205  pips_debug(5, "anywhere case \n");
206 
207  FOREACH(CELL_RELATION, pv_in, l_in)
208  {
209  cell_relation pv_out = copy_cell_relation(pv_in);
211  l_out = CONS(CELL_RELATION, pv_out, l_out);
212  }
213  }
214  else
215  {
216  /* eff_kill characteristics */
217  cell cell_kill = effect_cell(eff_kill);
218  tag app_kill = effect_approximation_tag(eff_kill);
219  reference ref_kill = effect_any_reference(eff_kill);
220  entity e_kill = reference_variable(ref_kill);
221  list ind_kill = reference_indices(ref_kill);
222  size_t nb_ind_kill = gen_length(ind_kill);
223  /******/
224 
225  /* using old_values, take into account the impact of eff_kill on
226  * l_in pointer values second cells which must be expressed in terms of
227  * unchanged paths.
228  */
229  list l_remnants = NIL;
230  cell_relation exact_old_pv = cell_relation_undefined;
231  list l_old_values = NIL;
232 
233  pips_debug(4, "begin, looking for an exact old value for eff_orig\n");
234 
235  l_old_values = effect_find_equivalent_pointer_values(eff_kill, l_in,
236  &exact_old_pv,
237  &l_remnants);
238  pips_debug_pvs(3, "l_old_values:", l_old_values);
239  pips_debug_pvs(3, "l_remnants:", l_remnants);
240  pips_debug_pv(3, "exact_old_pv:", exact_old_pv);
241 
242  list l_keep = NIL;
243  FOREACH(CELL_RELATION, pv_in, l_remnants)
244  {
245  bool first_p = false; /* should we translate the first or the second pv_in cell */
246  bool to_be_translated = false; /* must it be translated ? */
247  bool exact_preceding_test = true;
248 
249  /* pv_in first cell characteristics */
250  cell cell_in_1 = cell_relation_first_cell(pv_in);
251  reference ref_in_1 = cell_reference(cell_in_1);
252  entity e_in_1 = reference_variable(ref_in_1);
253  list ind_in_1 = reference_indices(ref_in_1);
254  size_t nb_ind_in_1 = gen_length(ind_in_1);
255  /******/
256 
257  /* pv_in second cell characteristics */
258  cell cell_in_2 = cell_relation_second_cell(pv_in);
259  reference ref_in_2 = cell_reference(cell_in_2);
260  entity e_in_2 = reference_variable(ref_in_2);
261  list ind_in_2 = reference_indices(ref_in_2);
262  size_t nb_ind_in_2 = gen_length(ind_in_2);
263  /******/
264 
265  pips_debug_pv(3, "considering pv_in:", pv_in);
266 
267  if (same_entity_p(e_kill, e_in_2) && nb_ind_kill <= nb_ind_in_2)
268  {
269  if (cell_relation_second_address_of_p(pv_in) && nb_ind_kill == nb_ind_in_2)
270  {
271  /* pointer value relation is still valid */
272  pips_debug(3, "address_of case, and nb_ind_in == nb_ind_kill_2\n");
273  to_be_translated = false;
274  }
275  else
276  {
277  pips_debug(3, "second cell is candidate for translation\n");
278  first_p = false;
279  bool inclusion_test_exact_p = false;
280  if ( (nb_ind_kill == nb_ind_in_2 &&
282  cell_kill, descriptor_undefined, &inclusion_test_exact_p))
283  ||
284  (nb_ind_kill < nb_ind_in_2 &&
286  ref_in_2, descriptor_undefined,
288  true,
289  &exact_preceding_test)))
290  to_be_translated = true;
291  else to_be_translated = false;
292  }
293  }
294  else if (same_entity_p(e_kill, e_in_1) && nb_ind_kill <= nb_ind_in_1)
295  {
296  pips_debug(3, "first cell is candidate for translation\n");
297  first_p = true;
298  bool inclusion_test_exact_p = false;
299  if ( (nb_ind_kill == nb_ind_in_1 &&
301  cell_kill, descriptor_undefined,
302  &inclusion_test_exact_p) )
303  ||
304  (nb_ind_kill < nb_ind_in_1 &&
306  ref_in_1, descriptor_undefined,
308  true,
309  &exact_preceding_test)))
310  to_be_translated = true;
311  else to_be_translated = false;
312  }
313  else
314  {
315  to_be_translated = false;
316  }
317 
318  if (to_be_translated)
319  {
320  pips_debug(3, "%s cell must be translated\n", first_p ? "first" : "second");
321 
322  /* This should be made generic */
323 
324  /* we must translate ref_in using the old_values */
325  /* if there is an exact candidate, it is ranked first
326  * and we can use it */
327  if (exact_old_pv != cell_relation_undefined)
328  {
329  cell_relation new_pv = simple_pv_translate(pv_in, first_p, exact_old_pv);
330  pips_debug_pv(3, "translated to:", new_pv);
331  l_out = CONS(CELL_RELATION, new_pv, l_out);
332  }
333  else /* generate a new pv for each element of old_values */
334  {
335  FOREACH(CELL_RELATION, old_pv, l_old_values) {
336  cell_relation new_pv = simple_pv_translate(pv_in, first_p, old_pv);
337  pips_debug_pv(3, "translated to:", new_pv);
338  l_out = CONS(CELL_RELATION, new_pv, l_out);
339  } /* FOREACH(CELL_RELATION, old_pv, l_old_values) */
340  } /* else branch of if (exact_first_pv) */
341  } /* if (to_be_translated) */
342  else
343  {
344  pips_debug(3, "non matching case, keep as is\n");
345  l_keep = CONS(CELL_RELATION, copy_cell_relation(pv_in), l_keep);
346  }
347  } /* FOREACH (CELL_RELATION, pv_in, l_remnants) */
348 
349  list l_tmp = (*ctxt->pvs_must_union_func)(l_out, l_keep);
350  //gen_full_free_list(l_out);
351  //gen_full_free_list(l_keep);
352  l_out = l_tmp;
353 
354  /* Second, take into account the impact of eff_kill on l_old_values relations.
355  * We only have to keep those which are not completely killed by kill_eff, and
356  * set their approximation to may (this is also true for exact_old_pv)
357  */
358 
359  /* first use exact_old_pv to translate exact old_values */
361  if (!cell_relation_undefined_p(exact_old_pv))
362  {
363  pips_debug(3, "handling exact_old_pv\n");
364  reference ref_old =
366  if(same_entity_p(reference_variable(ref_old),e_kill))
367  {
368  pips_debug(3, "exact_old_pv is inverted -> translate\n");
369  tmp_old_pv = make_value_of_pointer_value
370  (copy_cell(cell_relation_second_cell(exact_old_pv)),
371  copy_cell(cell_relation_first_cell(exact_old_pv)),
372  cell_relation_approximation_tag(exact_old_pv),
374  }
375  else
376  {
377  pips_debug(3, "exact_old_pv is not inverted\n");
378  tmp_old_pv = copy_cell_relation(exact_old_pv);
379  }
380  }
381 
382  /* Then the other old_values */
383  pips_debug(3, "dealing with old values\n");
384  FOREACH(CELL_RELATION, pv_old, l_old_values)
385  {
386  pips_debug_pv(3, "dealing with pv_old:", pv_old);
387  /* we already know that there may be a non-empty
388  * intersection with cell_kill */
389  if (app_kill == is_approximation_may)
390  {
391  pips_debug(3, "may kill, just change the approximation\n");
392  cell_relation pv_out = copy_cell_relation(pv_old);
394  l_out = CONS(CELL_RELATION, pv_out, l_out);
395  }
396  else /* some more work is necessary */
397  {
398  cell first_cell_old = cell_relation_first_cell(pv_old);
399  bool exact_inclusion_p = false;
400  bool inclusion_p = simple_cells_inclusion_p(first_cell_old, descriptor_undefined,
401  cell_kill, descriptor_undefined,
402  &exact_inclusion_p);
403 
404  if (inclusion_p && exact_inclusion_p)
405  {
406  pips_debug(3, "first_cell_old exactly included in cell_kill"
407  " -> pv_old is translated or killed\n");
408  if(!cell_relation_undefined_p(tmp_old_pv)
411  || cell_relation_second_address_of_p(tmp_old_pv))))
412  {
413  cell_relation new_pv = simple_pv_translate(tmp_old_pv,
414  true,
415  pv_old);
416  pips_debug_pv(3, "translating to:", new_pv);
417  l_out = CONS(CELL_RELATION, new_pv, l_out);
418  }
419  }
420  else
421  {
422  cell second_cell_old = cell_relation_second_cell(pv_old);
423  bool exact_inclusion_p = false;
424  bool inclusion_p = simple_cells_inclusion_p(second_cell_old, descriptor_undefined,
425  cell_kill, descriptor_undefined,
426  &exact_inclusion_p);
427  if (inclusion_p && exact_inclusion_p)
428  {
429  pips_debug(3, "second_cell_old exactly included in "
430  "cell_kill -> pv_old is translated or killed\n");
431 
432  if(!cell_relation_undefined_p(tmp_old_pv))
433  {
434  cell_relation new_pv = simple_pv_translate(tmp_old_pv,
435  true,
436  pv_old);
437  pips_debug_pv(3, "translating to:", new_pv);
438  l_out = CONS(CELL_RELATION, new_pv, l_out);
439  }
440  }
441  else
442  {
443  pips_debug(3, "may be included case"
444  " -> keep with may approximation\n");
445  /* some more precise work could be done here by
446  * computing the difference between the pv_old
447  * first cell and cell_kill. I don't know if it
448  * would be really useful. So let us avoid too
449  * complex things for the moment.
450  */
451  cell_relation pv_out = copy_cell_relation(pv_old);
454  l_out = CONS(CELL_RELATION, pv_out, l_out);
455  }
456  }
457  }
458  }
459  gen_free_list(l_old_values);
460 
461  pips_debug(3, "dealing with exact_old_pv\n");
462  if (!cell_relation_undefined_p(tmp_old_pv))
463  {
464  cell first_cell_old = cell_relation_first_cell(tmp_old_pv);
465  bool exact_inclusion_p = false;
466  if (app_kill == is_approximation_may)
467  {
468  pips_debug(3,
469  "may kill, keep exact_old_pv with may approximation\n");
470  cell_relation pv_out = copy_cell_relation(exact_old_pv);
472  l_out = CONS(CELL_RELATION, pv_out, l_out);
473  }
474  else if (simple_cells_inclusion_p(first_cell_old, descriptor_undefined,
475  cell_kill, descriptor_undefined,
476  &exact_inclusion_p)
477  && exact_inclusion_p)
478  {
479  pips_debug(3, "first cell of exact_old_pv exactly included in cell_kill "
480  "-> exact_old_pv is killed\n");
481  }
482  else
483  {
484  pips_debug(3, "may be included case"
485  " -> keep with may approximation\n");
486  /* some more precise work could be done here by
487  * computing the difference between the pv_old
488  * first cell and cell_kill. I don't know if it
489  * would be really useful. So let us avoid too
490  * complex things for the moment.
491  */
492  cell_relation pv_out = copy_cell_relation(tmp_old_pv);
495  l_out = CONS(CELL_RELATION, pv_out, l_out);
496  }
497  free_cell_relation(tmp_old_pv);
498  }
499 
500  }
501  pips_debug_pvs(1, "returning:", l_out);
502 
503  return l_out;
504 }
void free_cell_relation(cell_relation p)
Definition: effects.c:308
cell_relation copy_cell_relation(cell_relation p)
CELL_RELATION.
Definition: effects.c:305
cell copy_cell(cell p)
CELL.
Definition: effects.c:246
#define pips_debug_effect(level, message, eff)
for debug
bool simple_cell_reference_preceding_p(reference, descriptor, reference, descriptor, transformer, bool, bool *)
eval.c
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define pips_debug_pv(level, message, pv)
#define effect_approximation_tag(eff)
#define cell_relation_second_cell(cr)
#define cell_relation_second_address_of_p(cr)
#define cell_relation_first_cell(cr)
bool abstract_pointer_value_cell_p(cell)
cell_relation make_value_of_pointer_value(cell, cell, tag, descriptor)
bool anywhere_effect_p(effect)
Is it an anywhere effect? ANYMMODULE:ANYWHERE
Definition: effects.c:346
#define cell_reference(x)
Definition: effects.h:469
#define cell_relation_undefined
Definition: effects.h:485
#define descriptor_undefined
Definition: effects.h:559
#define effect_cell(x)
Definition: effects.h:640
#define cell_relation_undefined_p(x)
Definition: effects.h:486
size_t gen_length(const list l)
Definition: list.c:150
int tag
TAG.
Definition: newgen_types.h:92
cell_relation simple_pv_translate(cell_relation pv_in, bool in_first_p, cell_relation pv_old)
list effect_find_equivalent_pointer_values(effect eff, list l_in, cell_relation *exact_aliased_pv, list *l_in_remnants)
find pointer_values in l_in which give (possible or exact) paths equivalent to eff.
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
#define reference_indices(x)
Definition: ri.h:2328
list(* pvs_must_union_func)(list, list)
BINARY OPERATORS.

References abstract_pointer_value_cell_p(), anywhere_effect_p(), cell_reference, CELL_RELATION, cell_relation_approximation_tag, cell_relation_first_cell, cell_relation_second_address_of_p, cell_relation_second_cell, cell_relation_undefined, cell_relation_undefined_p, CONS, copy_cell(), copy_cell_relation(), descriptor_undefined, effect_any_reference, effect_approximation_tag, effect_cell, effect_find_equivalent_pointer_values(), FOREACH, free_cell_relation(), gen_free_list(), gen_length(), is_approximation_may, make_descriptor_none(), make_value_of_pointer_value(), NIL, pips_debug, pips_debug_effect, pips_debug_pv, pips_debug_pvs, pv_context::pvs_must_union_func, reference_indices, reference_variable, same_entity_p(), simple_cell_reference_preceding_p(), simple_cells_inclusion_p(), simple_pv_translate(), and transformer_undefined.

Referenced by kill_pointer_values().

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

◆ kill_pointer_values()

list kill_pointer_values ( list  l_in,
list  l_kill,
pv_context ctxt 
)

eliminate the cells of l_kill from l_in

Parameters
l_killis the list of effects describing the cells to eliminated from l_in
l_inis the input list of pointer_values.
ctxtis a pointer on the pointer values analysis contex.
Returns
a list of newly allocated pointer_values
Parameters
l_inof cell_relations
l_killof effects
ctxttxt

Definition at line 155 of file pointer_values_operators.c.

158 {
159  list l_res = NIL;
160  pips_debug_pvs(5, "l_in =", l_in);
161  pips_debug_effects(5, "l_kill =", l_kill);
162 
163  if (ENDP(l_kill))
164  {
165  l_res = gen_full_copy_list(l_in);
166  }
167  else
168  {
169  l_res = l_in;
170  FOREACH(EFFECT, eff_kill, l_kill)
171  {
172  list l_cur = kill_pointer_value(eff_kill, l_res, ctxt);
173  if (l_res != l_in) gen_full_free_list(l_res);
174  l_res = l_cur;
175  }
176  }
177 
178  pips_debug_pvs(5, "returning :", l_res);
179  return l_res;
180 }
#define pips_debug_effects(level, message, l_eff)
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
list gen_full_copy_list(list l)
Copy a list structure with element copy.
Definition: list.c:535
list kill_pointer_value(effect eff_kill, list l_in, pv_context *ctxt)
eliminate the cell of eff_kill from l_in

References EFFECT, ENDP, FOREACH, gen_full_copy_list(), gen_full_free_list(), kill_pointer_value(), NIL, pips_debug_effects, and pips_debug_pvs.

Referenced by single_pointer_assignment_to_post_pv().

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

◆ kill_pv_undefined_p()

bool kill_pv_undefined_p ( void  )

◆ load_gen_pv()

cell_relations load_gen_pv ( statement  )

◆ load_kill_pv()

effects load_kill_pv ( statement  )

◆ load_pv()

◆ make_anywhere_anywhere_pvs()

list make_anywhere_anywhere_pvs ( void  )

Definition at line 237 of file pointer_values_analyses.c.

238 {
241  copy_cell(anywhere_c),
244  return (CONS(CELL_RELATION, pv, NIL));
245 }
cell make_cell_reference(reference _field_)
Definition: effects.c:293
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
entity entity_all_locations()
eturn ANY_MODULE:ANYWHERE (the top of the lattice)
cell_relation make_address_of_pointer_value(cell, cell, tag, descriptor)

References CELL_RELATION, CONS, copy_cell(), entity_all_locations(), is_approximation_may, make_address_of_pointer_value(), make_cell_reference(), make_descriptor_none(), make_reference(), and NIL.

Referenced by unstructured_to_post_pv().

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

◆ make_pv_results()

◆ make_simple_pv_context()

pv_context make_simple_pv_context ( void  )

Definition at line 119 of file pointer_values_analyses.c.

120 {
121  pv_context ctxt;
122 
123  ctxt.initial_pointer_values_p = false;
124 
135 
146  ctxt.stmt_stack = stack_make(statement_domain, 0, 0);
147  return ctxt;
148 }
void simple_cell_reference_with_address_of_cell_reference_translation(reference, descriptor, reference, descriptor, int, reference *, descriptor *, bool *)
void simple_cell_reference_with_value_of_cell_reference_translation(reference, descriptor, reference, descriptor, int, reference *, descriptor *, bool *)
stack stack_make(int, int, int)
allocation
Definition: stack.c:246
list simple_pvs_may_union(list, list)
list simple_pvs_must_union(list, list)
bool simple_pvs_syntactically_equal_p(list, list)
cell_relation simple_pv_composition_with_transformer(cell_relation, transformer)
list make_simple_pv_from_simple_effects(effect, effect, cell_interpretation, list)
pointer_values_operators.c
list db_get_in_simple_pv(const char *module_name)
void db_put_in_simple_pv(const char *module_name, list l_pv)
list db_get_program_simple_pv()
statement_cell_relations db_get_simple_pv(const char *module_name)
I don't know how to deal with these mappings if we have to analyse several modules at the same time w...
void db_put_initial_simple_pv(const char *module_name, list l_pv)
void db_put_program_simple_pv(list l_pv)
void db_put_simple_pv(const char *module_name, statement_cell_relations scr)
void db_put_out_simple_pv(const char *module_name, list l_pv)
list db_get_out_simple_pv(const char *module_name)
list db_get_initial_simple_pv(const char *module_name)
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
void(* cell_reference_with_value_of_cell_reference_translation_func)(reference, descriptor, reference, descriptor, int, reference *, descriptor *, bool *)
TRANSLATION OPERATORS.
bool(* cell_preceding_p_func)(cell, descriptor, cell, descriptor, transformer, bool, bool *)
COMPARISON OPERATORS.
list(* db_get_initial_pv_func)(const char *)
list(* make_pv_from_effects_func)(effect, effect, cell_interpretation, list)
statement_cell_relations (*db_get_gen_pv_func)(char *);
stack stmt_stack
STACKS.
list(* db_get_program_pv_func)()
void(* db_put_out_pv_func)(const char *, list)
void(* db_put_in_pv_func)(const char *, list)
void(* cell_reference_with_address_of_cell_reference_translation_func)(reference, descriptor, reference, descriptor, int, reference *, descriptor *, bool *)
void(* db_put_pv_func)(const char *, statement_cell_relations)
list(* pvs_may_union_func)(list, list)
list(* db_get_out_pv_func)(const char *)
void(* db_put_initial_pv_func)(const char *, list)
bool(* pvs_equal_p_func)(list, list)
void(* db_put_program_pv_func)(list)
cell_relation(* pv_composition_with_transformer_func)(cell_relation, transformer)
UNARY OPERATORS.

References pv_context::cell_preceding_p_func, pv_context::cell_reference_with_address_of_cell_reference_translation_func, pv_context::cell_reference_with_value_of_cell_reference_translation_func, pv_context::db_get_in_pv_func, db_get_in_simple_pv(), pv_context::db_get_initial_pv_func, db_get_initial_simple_pv(), pv_context::db_get_out_pv_func, db_get_out_simple_pv(), pv_context::db_get_program_pv_func, db_get_program_simple_pv(), pv_context::db_get_pv_func, db_get_simple_pv(), pv_context::db_put_in_pv_func, db_put_in_simple_pv(), pv_context::db_put_initial_pv_func, db_put_initial_simple_pv(), pv_context::db_put_out_pv_func, db_put_out_simple_pv(), pv_context::db_put_program_pv_func, db_put_program_simple_pv(), pv_context::db_put_pv_func, db_put_simple_pv(), pv_context::initial_pointer_values_p, pv_context::make_pv_from_effects_func, make_simple_pv_from_simple_effects(), pv_context::pv_composition_with_transformer_func, pv_context::pvs_equal_p_func, pv_context::pvs_may_union_func, pv_context::pvs_must_union_func, simple_cell_preceding_p(), simple_cell_reference_with_address_of_cell_reference_translation(), simple_cell_reference_with_value_of_cell_reference_translation(), simple_pv_composition_with_transformer(), simple_pvs_may_union(), simple_pvs_must_union(), simple_pvs_syntactically_equal_p(), stack_make(), statement_domain, and pv_context::stmt_stack.

Referenced by convex_effect_find_aliased_paths_with_pointer_values(), initial_simple_pointer_values(), print_code_simple_gen_kill_pointer_values(), print_code_simple_pointer_values(), program_simple_pointer_values(), simple_effect_to_constant_path_effects_with_pointer_values(), and simple_pointer_values().

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

◆ make_simple_pv_from_simple_effects()

list make_simple_pv_from_simple_effects ( effect  lhs_eff,
effect  rhs_eff,
cell_interpretation  ci,
list  l_in 
)

pointer_values_operators.c

Parameters
lhs_effhs_eff
rhs_effhs_eff
cii
l_in_in

Definition at line 57 of file pointer_values_operators.c.

58 {
59  cell_relation pv;
60  list l_pv = NIL;
61 
62  pips_debug(1,"begin for %s cell_interpretation and effects :\n", cell_interpretation_value_of_p(ci)? "value_of" : "address_of");
63  pips_debug_effect(2, "lhs_eff:", lhs_eff);
64  pips_debug_effect(2, "rhs_eff:", rhs_eff);
65 
66  tag lhs_t = effect_approximation_tag(lhs_eff);
67  tag rhs_t = effect_approximation_tag(rhs_eff);
68  tag t = approximation_and(lhs_t, rhs_t);
69 
70  pips_debug(5,"approximation before converting to store independent cells: %s\n",
71  t == is_approximation_exact ? "must": "may");
72 
74 
76 
77  cell rhs_c = effect_cell(rhs_eff);
78  bool changed_rhs_p = false;
79  bool changed_lhs_p = false;
80 
83  else
84  {
86  lhs_c = simple_cell_to_store_independent_cell(lhs_c, &changed_lhs_p);
87  rhs_c = simple_cell_to_store_independent_cell(rhs_c, &changed_rhs_p);
88  }
89 
90  if (changed_lhs_p || changed_rhs_p)
91  {
92  pips_debug(5, "approximation set to may after change to store independent cell\n");
94  }
95 
97  pv = make_value_of_pointer_value(lhs_c,
98  rhs_c,
99  t,
101  else
103  rhs_c,
104  t,
106 
107  bool exact_preceding_p;
111  true,
112  & exact_preceding_p))
113  {
114  list l_remnants = NIL;
115  cell_relation exact_old_pv = cell_relation_undefined;
116  list l_old_values = NIL;
117 
118  pips_debug(4, "lhs path is a predecessor of rhs path, looking for an exact old value for rhs_eff\n");
119 
120  l_old_values = effect_find_equivalent_pointer_values(lhs_eff, l_in,
121  &exact_old_pv,
122  &l_remnants);
123  gen_free_list(l_remnants);
124  if (!cell_relation_undefined_p(exact_old_pv))
125  {
126  cell_relation new_pv = simple_pv_translate(pv, false, exact_old_pv);
127  l_pv = CONS(CELL_RELATION, new_pv, l_pv);
128  }
129  else
130  {
131  FOREACH(CELL_RELATION, old_pv, l_old_values) {
132  cell_relation new_pv = simple_pv_translate(pv, false, old_pv);
133  l_pv = CONS(CELL_RELATION, new_pv, l_pv);
134  }
135  }
136  free_cell_relation(pv);
137  gen_free_list(l_old_values);
138  }
139  else
140  l_pv = CONS(CELL_RELATION, pv, l_pv);
141 
142  pips_debug_pvs(2, "generating:", l_pv);
143  pips_debug(1,"end\n");
144  return l_pv;
145 }
cell make_cell(enum cell_utype tag, void *val)
Definition: effects.c:290
cell simple_cell_to_store_independent_cell(cell, bool *)
bool undefined_pointer_value_cell_p(cell)
tag approximation_and(tag, tag)
tag approximation_and(tag t1, tag t2) input : two approximation tags.
Definition: effects.c:1198
@ is_cell_reference
Definition: effects.h:445
#define cell_interpretation_value_of_p(x)
Definition: effects.h:415
@ is_approximation_exact
Definition: effects.h:343

References approximation_and(), cell_interpretation_value_of_p, cell_reference, CELL_RELATION, cell_relation_undefined, cell_relation_undefined_p, CONS, copy_reference(), descriptor_undefined, effect_any_reference, effect_approximation_tag, effect_cell, effect_find_equivalent_pointer_values(), FOREACH, free_cell_relation(), gen_free_list(), is_approximation_exact, is_approximation_may, is_cell_reference, make_address_of_pointer_value(), make_cell(), make_descriptor_none(), make_undefined_pointer_value_cell(), make_value_of_pointer_value(), NIL, pips_debug, pips_debug_effect, pips_debug_pvs, simple_cell_reference_preceding_p(), simple_cell_to_store_independent_cell(), simple_pv_translate(), transformer_undefined, and undefined_pointer_value_cell_p().

Referenced by make_simple_pv_context().

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

◆ multiple_pointer_assignment_to_post_pv()

void multiple_pointer_assignment_to_post_pv ( effect  lhs_base_eff,
type  lhs_type,
list  l_rhs_base_eff,
list  l_rhs_base_kind,
bool  declaration_p,
list  l_in,
pv_results pv_res,
pv_context ctxt 
)

we could be more precise here on abstract locations

if (!anywhere_lhs_p)

lhs is not a pointer, but it is an array of pointers or an aggregate type with pointers....

In this case, it cannot be an address_of case

First, search for all accessible pointers

to work around the fact that exact effects are must effects

Then for each found pointer, do as if there were an assignment by translating the rhs path accordingly

build the list of corresponding rhs

should be refined

general case at least :-)

This is not generic, I should use a translation algorithm here I guess

first skip dimensions of kill_ref similar to lhs_base_ref

add the remaining dimensions to the copy of rhs_base_eff

while

if (!ENDP(l_lhs))

if (!anywhere_lhs_p)

Parameters
lhs_base_effhs_base_eff
lhs_typehs_type
l_rhs_base_eff_rhs_base_eff
l_rhs_base_kind_rhs_base_kind
declaration_peclaration_p
l_in_in
pv_resv_res
ctxttxt

Definition at line 1444 of file pointer_values_analyses.c.

1448 {
1449  list l_in_cur = l_in;
1450  cell rhs_base_cell = gen_length(l_rhs_base_eff) > 0
1451  ? effect_cell(EFFECT(CAR(l_rhs_base_eff))): cell_undefined;
1452  bool anywhere_lhs_p = false;
1453 
1454  pips_debug(1, "begin\n");
1455 
1456  pips_assert("assigning NULL to several pointers"
1457  " at the same time is forbidden!\n", !(!cell_undefined_p(rhs_base_cell) && null_pointer_value_cell_p(rhs_base_cell)));
1458 
1459  /* we could be more precise here on abstract locations */
1460  if (anywhere_effect_p(lhs_base_eff))
1461  {
1462  pips_assert("we cannot have an anywhere lhs for a declaration\n", !declaration_p);
1463  pips_debug(3, "anywhere lhs\n");
1464  anywhere_lhs_p = true;
1465 
1468 
1469  single_pointer_assignment_to_post_pv(lhs_base_eff, l_rhs_eff, l_rhs_kind, declaration_p, l_in_cur, pv_res, ctxt);
1470 
1471  gen_full_free_list(l_rhs_eff);
1472  gen_full_free_list(l_rhs_kind);
1473  }
1474  else /* if (!anywhere_lhs_p) */
1475  {
1476  /* lhs is not a pointer, but it is an array of pointers or an aggregate type
1477  with pointers.... */
1478  /* In this case, it cannot be an address_of case */
1479 
1480  /* First, search for all accessible pointers */
1482  (lhs_base_eff, lhs_type, is_action_write, false, 0, true);
1483  if(effect_exact_p(lhs_base_eff))
1484  effects_to_must_effects(l_lhs); /* to work around the fact that exact effects are must effects */
1485  pips_debug_effects(2, "l_lhs = ", l_lhs);
1486 
1487  /* Then for each found pointer, do as if there were an assignment by translating
1488  the rhs path accordingly
1489  */
1490  if (!ENDP(l_lhs))
1491  {
1492  list l_lhs_tmp = l_lhs;
1493  while (!anywhere_lhs_p && !ENDP(l_lhs_tmp))
1494  {
1495  /* build the list of corresponding rhs */
1496  effect lhs_eff = EFFECT(CAR(l_lhs_tmp));
1497  reference lhs_ref = effect_any_reference(lhs_eff);
1498  list lhs_dims = reference_indices(lhs_ref);
1499 
1500  reference lhs_base_ref = effect_any_reference(lhs_base_eff);
1501  size_t lhs_base_nb_dim = gen_length(reference_indices(lhs_base_ref));
1502  list l_rhs_eff = NIL;
1503  list l_rhs_kind = NIL;
1504 
1505  bool free_rhs_kind = false;
1506  list l_rhs_base_kind_tmp = l_rhs_base_kind;
1507  FOREACH(EFFECT, rhs_base_eff, l_rhs_base_eff)
1508  {
1509  effect rhs_eff = copy_effect(rhs_base_eff);
1510  cell_interpretation rhs_kind = CELL_INTERPRETATION(CAR(l_rhs_base_kind));
1511 
1512  if (!undefined_pointer_value_cell_p(rhs_base_cell)
1513  && !anywhere_effect_p(rhs_base_eff))
1514  {
1515  reference rhs_ref = effect_any_reference(rhs_eff);
1516  bool to_be_freed = false;
1517  type rhs_type = cell_reference_to_type(rhs_ref, &to_be_freed);
1518 
1519  if (!type_equal_p(lhs_type, rhs_type))
1520  {
1521  pips_debug(5, "not same lhs and rhs types generating anywhere rhs\n");
1522  rhs_eff = make_anywhere_effect(make_action_write_memory()); /* should be refined */
1524  free_rhs_kind = true;
1525  }
1526  else /* general case at least :-) */
1527  {
1528  /* This is not generic, I should use a translation algorithm here I guess */
1529  /* first skip dimensions of kill_ref similar to lhs_base_ref */
1530  list lhs_dims_tmp = lhs_dims;
1531  for(size_t i = 0; i < lhs_base_nb_dim; i++, POP(lhs_dims_tmp));
1532  /* add the remaining dimensions to the copy of rhs_base_eff */
1533  FOREACH(EXPRESSION, dim, lhs_dims_tmp)
1534  {
1535  // functions that can be pointed by effect_add_expression_dimension_func:
1536  // simple_effect_add_expression_dimension
1537  // convex_region_add_expression_dimension
1538  (*effect_add_expression_dimension_func)(rhs_eff, dim);
1539  }
1540  }
1541  if (to_be_freed) free_type(rhs_type);
1542  }
1543  l_rhs_eff = CONS(EFFECT, rhs_eff, l_rhs_eff);
1544  l_rhs_kind = CONS(CELL_INTERPRETATION, rhs_kind, l_rhs_kind);
1545  POP(l_rhs_base_kind_tmp);
1546  }
1547 
1548  single_pointer_assignment_to_post_pv(lhs_eff, l_rhs_eff, l_rhs_kind, declaration_p, l_in_cur, pv_res, ctxt);
1549 
1550  gen_full_free_list(l_rhs_eff);
1551  if (free_rhs_kind) gen_full_free_list(l_rhs_kind); else gen_free_list(l_rhs_kind);
1552 
1553  list l_out = pv_res->l_out;
1554  if (l_out != l_in_cur)
1555  gen_full_free_list(l_in_cur);
1556  l_in_cur = l_out;
1557 
1558  list l_result_paths = pv_res->result_paths;
1559 
1560  if (gen_length(l_result_paths) > 0 && anywhere_effect_p(EFFECT(CAR(l_result_paths))))
1561  anywhere_lhs_p = true;
1562 
1563  POP(l_lhs_tmp);
1564  } /* while */
1565  } /* if (!ENDP(l_lhs)) */
1566  gen_full_free_list(l_lhs);
1567  } /* if (!anywhere_lhs_p) */
1568 
1569  return;
1570 }
cell_interpretation make_cell_interpretation_address_of(void)
Definition: effects.c:240
void free_type(type p)
Definition: ri.c:2658
effect make_anywhere_effect(action)
void effects_to_must_effects(list)
list generic_effect_generate_all_accessible_paths_effects_with_level(effect, type, tag, bool, int, bool)
#define effect_exact_p(eff)
type cell_reference_to_type(reference, bool *)
computes the type of a cell reference representing a memory access path.
Definition: type.c:466
bool null_pointer_value_cell_p(cell)
#define cell_undefined_p(x)
Definition: effects.h:431
#define cell_undefined
Definition: effects.h:430
@ is_action_write
Definition: effects.h:293
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
bool type_equal_p(type, type)
Definition: type.c:547
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217

References anywhere_effect_p(), CAR, CELL_INTERPRETATION, cell_reference_to_type(), cell_undefined, cell_undefined_p, CONS, copy_effect(), EFFECT, effect_any_reference, effect_cell, effect_exact_p, effects_to_must_effects(), ENDP, EXPRESSION, FOREACH, free_type(), gen_free_list(), gen_full_free_list(), gen_length(), generic_effect_generate_all_accessible_paths_effects_with_level(), is_action_write, pv_results::l_out, make_action_write_memory(), make_anywhere_effect(), make_cell_interpretation_address_of(), NIL, null_pointer_value_cell_p(), pips_assert, pips_debug, pips_debug_effects, POP, reference_indices, pv_results::result_paths, single_pointer_assignment_to_post_pv(), type_equal_p(), and undefined_pointer_value_cell_p().

Referenced by assignment_to_post_pv().

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

◆ pointer_values_remove_var()

void pointer_values_remove_var ( entity  e,
bool  may_p,
list  l_in,
pv_results pv_res,
pv_context ctxt 
)

possibly assign an undefined value to pointers reachable from e without dereferencements)

Then replace all occurrences of e by an undefined value if it's not a may kill

Parameters
may_pay_p
l_in_in
pv_resv_res
ctxttxt

Definition at line 693 of file pointer_values_operators.c.

695 {
696  pips_debug(5, "begin for entity %s\n", entity_name(e));
697  pips_debug_pvs(5, "input l_in\n", l_in);
698 
699  /* possibly assign an undefined value to pointers reachable
700  from e without dereferencements) */
702  assignment_to_post_pv(exp, may_p,
704  false, l_in, pv_res, ctxt);
705  l_in = pv_res->l_out;
707 
708  /* Then replace all occurrences of e by an
709  undefined value if it's not a may kill */
710  if (!may_p)
711  {
712  list l_out = NIL;
713  FOREACH(CELL_RELATION, pv, l_in)
714  {
715  pips_debug_pv(5, "considering pv:", pv);
716  cell_relation new_pv = copy_cell_relation(pv);
717  cell c1 = cell_relation_first_cell(new_pv);
719 
720  cell c2 = cell_relation_second_cell(new_pv);
722  bool keep = true;
723 
724  if (same_entity_p(e1, e))
725  {
727  {
728  free_cell(c1);
731  }
732  else
733  keep = false;
734  }
735  else if (same_entity_p(e2, e))
736  {
738  {
739  free_cell(c2);
744  }
745  else keep = false;
746  }
747  if (keep)
748  l_out = CONS(CELL_RELATION, new_pv, l_out);
749  else
750  free_cell_relation(new_pv);
751  }
752  gen_full_free_list(l_in);
753  pv_res->l_out = l_out;
754  }
755  pips_debug_pvs(5, "end with pv_res->l_out = \n", pv_res->l_out );
756 }
void free_cell(cell p)
Definition: effects.c:249
void free_expression(expression p)
Definition: ri.c:853
#define cell_relation_second_interpretation_tag(cr)
@ is_cell_interpretation_value_of
Definition: effects.h:396
void assignment_to_post_pv(expression, bool, expression, bool, list, pv_results *, pv_context *)
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
#define expression_undefined
Definition: ri.h:1223
#define entity_name(x)
Definition: ri.h:2790
@ keep
bj > b1 -> h1/hj = h1
Definition: union-local.h:61

References assignment_to_post_pv(), cell_reference, CELL_RELATION, cell_relation_first_cell, cell_relation_second_cell, cell_relation_second_interpretation_tag, CONS, copy_cell_relation(), entity_name, entity_to_expression(), exp, expression_undefined, FOREACH, free_cell(), free_cell_relation(), free_expression(), gen_full_free_list(), is_cell_interpretation_value_of, keep, pv_results::l_out, make_undefined_pointer_value_cell(), NIL, pips_debug, pips_debug_pv, pips_debug_pvs, reference_variable, same_entity_p(), and undefined_pointer_value_cell_p().

Referenced by free_to_post_pv(), and sequence_to_post_pv().

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

◆ print_code_simple_gen_kill_pointer_values()

bool print_code_simple_gen_kill_pointer_values ( char *  module_name)
Parameters
module_nameodule_name

Definition at line 95 of file prettyprint.c.

96 {
99  reset_pv_context(&ctxt);
100  return(true);
101 }
void generic_print_code_gen_kill_pv(char *module_name)
Definition: prettyprint.c:90
pv_context make_simple_pv_context(void)
void reset_pv_context(pv_context *)

References generic_print_code_gen_kill_pv(), make_simple_pv_context(), module_name(), and reset_pv_context().

+ Here is the call graph for this function:

◆ print_code_simple_pointer_values()

bool print_code_simple_pointer_values ( char *  module_name)
Parameters
module_nameodule_name

Definition at line 82 of file prettyprint.c.

83 {
86  reset_pv_context(&ctxt);
87  return success;
88 }
bool generic_print_code_pv(char *module_name, pv_context *ctxt)
Definition: prettyprint.c:53

References generic_print_code_pv(), make_simple_pv_context(), module_name(), and reset_pv_context().

+ Here is the call graph for this function:

◆ print_pv_results()

void print_pv_results ( pv_results  pv_res)
Parameters
pv_resv_res

Definition at line 211 of file pointer_values_analyses.c.

212 {
213  fprintf(stderr, "l_out =");
214  print_pointer_values(pv_res.l_out);
215  list l_rp = pv_res.result_paths;
216  list l_rpi = pv_res.result_paths_interpretations;
217 
218  if (!ENDP(l_rp))
219  {
220  fprintf(stderr, "result_paths are:\n");
221  for(; !ENDP(l_rp); POP(l_rp), POP(l_rpi))
222  {
223  effect eff = EFFECT(CAR(l_rp));
225  fprintf(stderr, "%s:",
227  ? "value of" : "address of");
228  (*effect_prettyprint_func)(eff);
229  }
230  }
231  else
232  fprintf(stderr, "result_path is undefined\n");
233 }
void print_pointer_values(list)
Definition: prettyprint.c:622
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...

References CAR, CELL_INTERPRETATION, cell_interpretation_value_of_p, EFFECT, ENDP, fprintf(), pv_results::l_out, POP, print_pointer_values(), pv_results::result_paths, and pv_results::result_paths_interpretations.

+ Here is the call graph for this function:

◆ program_simple_pointer_values()

bool program_simple_pointer_values ( const  string)
Parameters
stringrog_name

Definition at line 1936 of file pointer_values_analyses.c.

1937 {
1940  generic_program_pointer_values(prog_name, &ctxt);
1941  reset_pv_context(&ctxt);
1943  return(true);
1944 }
static void generic_program_pointer_values(char *prog_name, pv_context *ctxt)

References generic_effects_reset_all_methods(), generic_program_pointer_values(), make_simple_pv_context(), reset_pv_context(), and set_methods_for_simple_effects().

+ Here is the call graph for this function:

◆ pv_context_statement_head()

statement pv_context_statement_head ( pv_context ctxt)
Parameters
ctxttxt

Definition at line 187 of file pointer_values_analyses.c.

188 {
189  return ((statement) stack_head(ctxt->stmt_stack));
190 }
void * stack_head(const stack)
returns the item on top of stack s
Definition: stack.c:420

References stack_head(), and pv_context::stmt_stack.

Referenced by heap_intrinsic_to_post_pv().

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

◆ pv_context_statement_pop()

void pv_context_statement_pop ( pv_context ctxt)
Parameters
ctxttxt

Definition at line 182 of file pointer_values_analyses.c.

183 {
184  (void) stack_pop( ctxt->stmt_stack);
185 }
void * stack_pop(stack)
POPs one item from stack s.
Definition: stack.c:399

References stack_pop(), and pv_context::stmt_stack.

Referenced by sequence_to_post_pv(), and statement_to_post_pv().

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

◆ pv_context_statement_push()

void pv_context_statement_push ( statement  s,
pv_context ctxt 
)
Parameters
ctxttxt

Definition at line 177 of file pointer_values_analyses.c.

178 {
179  stack_push((void *) s, ctxt->stmt_stack);
180 }
void stack_push(void *, stack)
stack use
Definition: stack.c:373

References stack_push(), and pv_context::stmt_stack.

Referenced by sequence_to_post_pv(), and statement_to_post_pv().

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

◆ pv_undefined_p()

bool pv_undefined_p ( void  )

cproto-generated files

pointer_values_analyses.c

◆ pvs_composition_with_transformer()

list pvs_composition_with_transformer ( list  l_pv,
transformer  t,
pv_context ctxt 
)
Parameters
l_pv_pv
ctxttxt

Definition at line 788 of file pointer_values_operators.c.

789 {
790  FOREACH(CELL_RELATION, pv, l_pv)
791  {
792  pv = (*ctxt->pv_composition_with_transformer_func)(pv, t);
793  }
794 
795  return l_pv;
796 }

References CELL_RELATION, FOREACH, and pv_context::pv_composition_with_transformer_func.

Referenced by statement_to_post_pv().

+ Here is the caller graph for this function:

◆ pvs_union_combinable_p()

bool pvs_union_combinable_p ( cell_relation  pv1,
cell_relation  pv2 
)
Parameters
pv1v1
pv2v2

Definition at line 965 of file pointer_values_operators.c.

966 {
967  bool undef1 = cell_relation_undefined_p(pv1);
968  bool undef2 = cell_relation_undefined_p(pv2);
969 
970  pips_assert("error: there should be no undefined cell_relations in lists\n", !(undef1 && undef2));
971 
972  if (undef1 || undef2) return true;
973  if (pv_cells_mergeable_p(pv1, pv2)) return true;
974 
975 
976  cell c_first_1 = cell_relation_first_cell(pv1);
977  cell c_second_1 = cell_relation_second_cell(pv1);
978 
979  cell c_first_2 = cell_relation_first_cell(pv2);
980  cell c_second_2 = cell_relation_second_cell(pv2);
981 
982  if (entity_all_locations_p(cell_entity(c_second_1))
984  {
985  int n_first_first = cell_compare(&c_first_1, &c_first_2);
986  if (n_first_first == 0) return true;
987  int n_first_second = cell_compare(&c_first_1, &c_second_2);
988  if (n_first_second == 0) return true;
989  }
990  if (entity_all_locations_p(cell_entity(c_second_2))
992  {
993  int n_first_first = cell_compare(&c_first_1, &c_first_2);
994  if (n_first_first == 0) return true;
995  int n_second_first = cell_compare(&c_second_1, &c_first_2);
996  if (n_second_first == 0) return true;
997  }
998 
999  return false;
1000 
1001 }
bool entity_all_locations_p(entity e)
test if an entity is the top of the lattice
int cell_compare(cell *c1, cell *c2)
Definition: compare.c:168
#define cell_relation_second_value_of_p(cr)
bool pv_cells_mergeable_p(cell_relation, cell_relation)
entity cell_entity(cell)
Definition: effects.c:57

References cell_compare(), cell_entity(), cell_relation_first_cell, cell_relation_second_cell, cell_relation_second_value_of_p, cell_relation_undefined_p, entity_all_locations_p(), pips_assert, and pv_cells_mergeable_p().

Referenced by simple_pvs_may_union(), and simple_pvs_must_union().

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

◆ range_to_post_pv()

void range_to_post_pv ( range  r,
list  l_in,
pv_results pv_res,
pv_context ctxt 
)
Parameters
l_in_in
pv_resv_res
ctxttxt

Definition at line 913 of file pointer_values_analyses.c.

914 {
915  expression el = range_lower(r);
916  expression eu = range_upper(r);
917  expression ei = range_increment(r);
918 
919  pips_debug(1, "begin\n");
920 
921  expression_to_post_pv(el, l_in, pv_res, ctxt);
922  expression_to_post_pv(eu, pv_res->l_out, pv_res, ctxt);
923  expression_to_post_pv(ei, pv_res->l_out, pv_res, ctxt);
924 
925  free_pv_results_paths(pv_res);
926 
927  pips_debug_pvs(1, "end with pv_res->l_out:\n", pv_res->l_out);
928 }
#define range_upper(x)
Definition: ri.h:2290
#define range_increment(x)
Definition: ri.h:2292
#define range_lower(x)
Definition: ri.h:2288

References expression_to_post_pv(), free_pv_results_paths(), pv_results::l_out, pips_debug, pips_debug_pvs, range_increment, range_lower, and range_upper.

Referenced by loop_to_post_pv().

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

◆ reset_gen_pv()

void reset_gen_pv ( void  )

◆ reset_kill_pv()

void reset_kill_pv ( void  )

◆ reset_pv()

void reset_pv ( void  )

Referenced by generic_module_initial_pointer_values(), generic_module_pointer_values(), and generic_print_code_pv().

+ Here is the caller graph for this function:

◆ reset_pv_context()

void reset_pv_context ( pv_context p_ctxt)

p_ctxt->db_get_gen_pv_func =(statement_cell_relations_function) UNDEF ;

p_ctxt->db_put_gen_pv_func = (void_function) UNDEF;

p_ctxt->db_get_kill_pv_func = (statement_effects_function) UNDEF;

p_ctxt->db_put_kill_pv_func = (void_function) UNDEF;

Parameters
p_ctxt_ctxt

Definition at line 162 of file pointer_values_analyses.c.

163 {
165  p_ctxt->db_put_pv_func = (void_function) UNDEF;
166 /* p_ctxt->db_get_gen_pv_func =(statement_cell_relations_function) UNDEF ; */
167 /* p_ctxt->db_put_gen_pv_func = (void_function) UNDEF; */
168 /* p_ctxt->db_get_kill_pv_func = (statement_effects_function) UNDEF; */
169 /* p_ctxt->db_put_kill_pv_func = (void_function) UNDEF; */
175 }
statement_cell_relations(* statement_cell_relations_function)()
void(* void_function)()
bool(* bool_function)()
list(* list_function)()
#define UNDEF
cell_relation(* cell_relation_function)()

References pv_context::db_get_pv_func, pv_context::db_put_pv_func, pv_context::make_pv_from_effects_func, pv_context::pv_composition_with_transformer_func, pv_context::pvs_equal_p_func, pv_context::pvs_may_union_func, pv_context::pvs_must_union_func, and UNDEF.

Referenced by convex_effect_find_aliased_paths_with_pointer_values(), initial_simple_pointer_values(), print_code_simple_gen_kill_pointer_values(), print_code_simple_pointer_values(), program_simple_pointer_values(), simple_effect_to_constant_path_effects_with_pointer_values(), and simple_pointer_values().

+ Here is the caller graph for this function:

◆ set_gen_pv()

void set_gen_pv ( statement_cell_relations  )

◆ set_kill_pv()

void set_kill_pv ( statement_effects  )

◆ set_pv()

void set_pv ( statement_cell_relations  )

Referenced by generic_print_code_pv().

+ Here is the caller graph for this function:

◆ simple_pointer_values()

bool simple_pointer_values ( const  string)

interface to compute the simple pointer values of a given module

Parameters
stringodule_name

Definition at line 1915 of file pointer_values_analyses.c.

1916 {
1920  reset_pv_context(&ctxt);
1922  return(true);
1923 }
static void generic_module_pointer_values(char *module_name, pv_context *ctxt)
generic interface to compute the pointer values of a given module

References generic_effects_reset_all_methods(), generic_module_pointer_values(), make_simple_pv_context(), module_name(), reset_pv_context(), and set_methods_for_simple_effects().

+ Here is the call graph for this function:

◆ simple_pv_composition_with_transformer()

cell_relation simple_pv_composition_with_transformer ( cell_relation  ,
transformer   
)

Referenced by make_simple_pv_context().

+ Here is the caller graph for this function:

◆ simple_pv_may_union()

list simple_pv_may_union ( cell_relation  pv1,
cell_relation  pv2 
)
Parameters
pv1v1
pv2v2

Definition at line 891 of file pointer_values_operators.c.

892 {
893  cell c_first_1 = cell_relation_first_cell(pv1);
894  cell c_second_1 = cell_relation_second_cell(pv1);
895 
896  cell c_first_2 = cell_relation_first_cell(pv2);
897  cell c_second_2 = cell_relation_second_cell(pv2);
898 
899  cell_relation pv;
900  if (entity_all_locations_p(cell_entity(c_second_1)))
901  {
902  pips_debug(5, "pv1 second cell is anywhere\n");
904  copy_cell(c_second_1),
907  }
908  else if (entity_all_locations_p(cell_entity(c_second_2)))
909  {
910  pips_debug(5, "pv2 second cell is anywhere\n");
912  copy_cell(c_second_2),
915  }
916  else
917  {
918  if ((cell_compare(&c_first_1, &c_first_2) == 0
919  && cell_compare(&c_second_1, &c_second_2) == 0)
920  || (cell_compare(&c_first_1, &c_second_2) == 0
921  && cell_compare(&c_second_1, &c_first_2) == 0)
922  )
923  {
924 
927  tag t;
928 
929  if (t1 == t2) t = t1;
930  else t = is_approximation_may;
931 
932  pv = copy_cell_relation(pv1);
934  }
935  else
936  {
937  // first cells are equal, but not second cells indices
938  // generate a pv with an unbounded dimension wherever dimensions
939  // are not equal
940  pv = copy_cell_relation(pv1);
942 
943  cell c_second_pv = cell_relation_second_cell(pv);
944  list l_ind_c_second_pv = reference_indices(cell_any_reference(c_second_pv));
945  list l_ind_c_second_2 = reference_indices(cell_any_reference(c_second_2));
946 
947  for(; !ENDP(l_ind_c_second_pv); POP(l_ind_c_second_pv), POP(l_ind_c_second_2))
948  {
949  expression ind_pv = EXPRESSION(CAR(l_ind_c_second_pv));
950  expression ind_2 = EXPRESSION(CAR(l_ind_c_second_2));
951 
952  if (!expression_equal_p(ind_pv, ind_2))
953  {
954  EXPRESSION_(CAR(l_ind_c_second_pv)) = make_unbounded_expression();
955  }
956  }
957 
958  }
959  }
960  list l_res = CONS(CELL_RELATION, pv, NIL);
961  pips_debug_pvs(5, "returning:\n", l_res);
962  return l_res;
963 }
reference cell_any_reference(cell)
API for reference.
Definition: effects.c:77
expression make_unbounded_expression()
Definition: expression.c:4339
bool expression_equal_p(expression e1, expression e2)
Syntactic equality e1==e2.
Definition: expression.c:1347
#define EXPRESSION_(x)
Definition: ri.h:1220

References CAR, cell_any_reference(), cell_compare(), cell_entity(), CELL_RELATION, cell_relation_approximation_tag, cell_relation_first_cell, cell_relation_second_cell, CONS, copy_cell(), copy_cell_relation(), ENDP, entity_all_locations_p(), EXPRESSION, EXPRESSION_, expression_equal_p(), is_approximation_may, make_address_of_pointer_value(), make_descriptor_none(), make_unbounded_expression(), NIL, pips_debug, pips_debug_pvs, POP, and reference_indices.

Referenced by simple_pvs_may_union().

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

◆ simple_pv_must_union()

list simple_pv_must_union ( cell_relation  pv1,
cell_relation  pv2 
)
Parameters
pv1v1
pv2v2

Definition at line 811 of file pointer_values_operators.c.

812 {
813  pips_debug_pv(5, "pv1 =\n", pv1);
814  pips_debug_pv(5, "pv2 =\n", pv2);
815 
816  cell c_first_1 = cell_relation_first_cell(pv1);
817  cell c_second_1 = cell_relation_second_cell(pv1);
818 
819  cell c_first_2 = cell_relation_first_cell(pv2);
820  cell c_second_2 = cell_relation_second_cell(pv2);
821 
823  if (entity_all_locations_p(cell_entity(c_second_1)))
824  {
825  pips_debug(5, "pv1 second cell is anywhere\n");
827  copy_cell(c_second_1),
830  }
831  else if (entity_all_locations_p(cell_entity(c_second_2)))
832  {
833  pips_debug(5, "pv2 second cell is anywhere\n");
835  copy_cell(c_second_2),
838  }
839  else
840  {
841  pips_debug(5, "general case\n");
842  if ((cell_compare(&c_first_1, &c_first_2) == 0
843  && cell_compare(&c_second_1, &c_second_2) == 0)
844  || (cell_compare(&c_first_1, &c_second_2) == 0
845  && cell_compare(&c_second_1, &c_first_2) == 0)
846  )
847  {
848 
851  tag t;
852 
853  if (t1 == t2) t = t1;
854  else t = is_approximation_exact;
855 
856  pv = copy_cell_relation(pv1);
858  }
859  else
860  {
861 
862  // first cells are equal, but not second cells indices
863  // generate a pv with an unbounded dimension wherever dimensions
864  // are not equal
865  pv = copy_cell_relation(pv1);
867 
868  cell c_second_pv = cell_relation_second_cell(pv);
869  list l_ind_c_second_pv = reference_indices(cell_any_reference(c_second_pv));
870  list l_ind_c_second_2 = reference_indices(cell_any_reference(c_second_2));
871 
872  for(; !ENDP(l_ind_c_second_pv); POP(l_ind_c_second_pv), POP(l_ind_c_second_2))
873  {
874  expression ind_pv = EXPRESSION(CAR(l_ind_c_second_pv));
875  expression ind_2 = EXPRESSION(CAR(l_ind_c_second_2));
876 
877  if (!expression_equal_p(ind_pv, ind_2))
878  {
879  EXPRESSION_(CAR(l_ind_c_second_pv)) = make_unbounded_expression();
880  }
881  }
882 
883  }
884  }
885  pips_debug_pv(5, "pv =\n", pv);
886  list l_res = CONS(CELL_RELATION, pv, NIL);
887  pips_debug_pvs(5, "returning:\n", l_res);
888  return l_res;
889 }

References CAR, cell_any_reference(), cell_compare(), cell_entity(), CELL_RELATION, cell_relation_approximation_tag, cell_relation_first_cell, cell_relation_second_cell, cell_relation_undefined, CONS, copy_cell(), copy_cell_relation(), ENDP, entity_all_locations_p(), EXPRESSION, EXPRESSION_, expression_equal_p(), is_approximation_exact, is_approximation_may, make_address_of_pointer_value(), make_descriptor_none(), make_unbounded_expression(), NIL, pips_debug, pips_debug_pv, pips_debug_pvs, POP, and reference_indices.

Referenced by simple_pvs_must_union().

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

◆ simple_pv_translate()

cell_relation simple_pv_translate ( cell_relation  pv_in,
bool  in_first_p,
cell_relation  pv_old 
)
Parameters
pv_ina the input pointer_value relation
in_first_pis true (false) if the first (second) cell of pv_in has to be translated
pv_oldis the cell relation that gives the value of a prefix path of the first (second) cell of pv_in
Returns
a newly allocated pointer_value relation in which the first (second) has been translated.

pv_in first or second cell characteristics

pv_old characteristics

is the first cell of pv_old the prefix of ref_in?

act as if there were a [0] indice at the end of ref_old_1

not generic here

not generic here

not generic here

not generic here

not generic here

not generic here

Parameters
pv_inv_in
in_first_pn_first_p
pv_oldv_old

Definition at line 513 of file pointer_values_operators.c.

514 {
515  cell_relation pv_new;
516 
517  pips_debug_pv(5, "pv_in =", pv_in);
518  pips_debug(5, "translating %s cell\n", in_first_p? "first": "second");
519  pips_debug_pv(5, "pv_old =", pv_old);
520 
521  /* pv_in first or second cell characteristics */
522  cell cell_in = in_first_p ? cell_relation_first_cell(pv_in) : cell_relation_second_cell(pv_in);
523  reference ref_in = cell_reference(cell_in);
524  entity e_in = reference_variable(ref_in);
525  list ind_in = reference_indices(ref_in);
526  size_t nb_ind_in = gen_length(ind_in);
527  /******/
528 
529  /* pv_old characteristics */
530  reference ref_old_1 =
532  list ind_old_1 = reference_indices(ref_old_1);
533  size_t nb_ind_old_1 = gen_length(ind_old_1);
534 
535  reference ref_old_2 =
537  list ind_old_2 = reference_indices(ref_old_2);
538  size_t nb_ind_old_2 = gen_length(ind_old_2);
539  bool anywhere_old_p = cell_relation_second_address_of_p(pv_old)
541  /******/
542 
543  bool old_first_p = same_entity_p(reference_variable(ref_old_1), e_in); /* is the first cell of pv_old the prefix of ref_in? */
544 
545  //reference prefix_ref = old_first_p ? ref_old_1 : ref_old_2;
546  reference target_ref = old_first_p ? ref_old_2 : ref_old_1;
547 
548  reference ref;
549  descriptor d;
550  bool exact_translation_p;
551  int nb_common_indices;
552  bool address_of_ref = false;
553 
554  if (old_first_p && anywhere_old_p)
555  {
556  cell c1 = in_first_p ? copy_cell(cell_relation_second_cell(pv_in)) :
559  pv_new = make_address_of_pointer_value(c1, c2,
561  }
562  else
563  {
564  if ( (!old_first_p) && cell_relation_second_address_of_p(pv_old))
565  {
566  /* act as if there were a [0] indice at the end of ref_old_1 */
567  nb_common_indices = (int) nb_ind_old_1 + 1;
568 
570  (ref_in, descriptor_undefined, /* not generic here */
571  target_ref, descriptor_undefined, /* not generic here */
572  nb_common_indices,
573  &ref, &d, &exact_translation_p);
574 
575  }
576  else
577  {
578  nb_common_indices = old_first_p ? (int) nb_ind_old_1 : (int) nb_ind_old_2;
579 
581  {
582  if (nb_ind_in == 0)
583  {
584  ref = copy_reference(target_ref);
585  exact_translation_p = true;
586  address_of_ref = true;
587  }
588  else
590  (ref_in, descriptor_undefined, /* not generic here */
591  target_ref, descriptor_undefined, /* not generic here */
592  nb_common_indices,
593  &ref, &d, &exact_translation_p);
594  }
595  else
597  (ref_in, descriptor_undefined, /* not generic here */
598  target_ref, descriptor_undefined, /* not generic here */
599  nb_common_indices,
600  &ref, &d, &exact_translation_p);
601  }
602  pips_debug(5, "ref after translation %s\n",
604 
605  tag new_t = (cell_relation_may_p(pv_in) || cell_relation_may_p(pv_old) || !exact_translation_p)
607 
608  if (in_first_p)
609  {
611  {
612  if (!address_of_ref)
615  new_t, make_descriptor_none());
616  else
619  new_t, make_descriptor_none());
620  }
621  else
622  {
623  pips_assert("pointer values do not have two address of cells\n", !address_of_ref);
626  new_t, make_descriptor_none());
627  }
628  }
629  else
630  {
631  if(cell_relation_second_value_of_p(pv_in) && !address_of_ref )
634  new_t, make_descriptor_none());
635  else
638  new_t, make_descriptor_none());
639  }
640  }
641  return pv_new;
642 }
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
void const char const char const int
#define cell_relation_may_p(cr)
string reference_to_string(reference r)
Definition: expression.c:87

References cell_reference, cell_relation_first_cell, cell_relation_may_p, cell_relation_second_address_of_p, cell_relation_second_cell, cell_relation_second_value_of_p, copy_cell(), copy_reference(), descriptor_undefined, entity_all_locations_p(), gen_length(), int, is_approximation_exact, is_approximation_may, make_address_of_pointer_value(), make_cell_reference(), make_descriptor_none(), make_value_of_pointer_value(), pips_assert, pips_debug, pips_debug_pv, ref, reference_indices, reference_to_string(), reference_variable, same_entity_p(), simple_cell_reference_with_address_of_cell_reference_translation(), and simple_cell_reference_with_value_of_cell_reference_translation().

Referenced by kill_pointer_value(), and make_simple_pv_from_simple_effects().

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

◆ simple_pvs_may_union()

list simple_pvs_may_union ( list  l_pv1,
list  l_pv2 
)
Parameters
l_pv1_pv1
l_pv2_pv2

Definition at line 1029 of file pointer_values_operators.c.

1030 {
1031 
1033  l_pv1,
1034  l_pv2,
1039  return l_res;
1040 }
list cell_relations_generic_binary_op(list l1, list l2, bool(*cr1_cr2_combinable_p)(cell_relation, cell_relation), list(*cr1_cr2_binary_op)(cell_relation, cell_relation), list(*cr1_unary_op)(cell_relation), list(*cr2_unary_op)(cell_relation), list(*union_op)(list, list))
functions specific to cell_relations
bool pvs_union_combinable_p(cell_relation pv1, cell_relation pv2)
list simple_pv_may_union(cell_relation pv1, cell_relation pv2)
list simple_pvs_must_union(list l_pv1, list l_pv2)
list cell_relation_to_may_list(cell_relation cr)

References cell_relation_to_may_list(), cell_relations_generic_binary_op(), pvs_union_combinable_p(), simple_pv_may_union(), and simple_pvs_must_union().

Referenced by make_simple_pv_context().

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

◆ simple_pvs_must_union()

list simple_pvs_must_union ( list  l_pv1,
list  l_pv2 
)
Parameters
l_pv1_pv1
l_pv2_pv2

Definition at line 1010 of file pointer_values_operators.c.

1011 {
1012 
1014  l_pv1,
1015  l_pv2,
1020  return l_res;
1021 }
list simple_pv_must_union(cell_relation pv1, cell_relation pv2)
list cell_relation_to_list(cell_relation cr)

References cell_relation_to_list(), cell_relations_generic_binary_op(), pvs_union_combinable_p(), simple_pv_must_union(), and simple_pvs_must_union().

Referenced by make_simple_pv_context(), simple_pvs_may_union(), and simple_pvs_must_union().

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

◆ simple_pvs_syntactically_equal_p()

bool simple_pvs_syntactically_equal_p ( list  l_pv1,
list  l_pv2 
)

first sort lists

then compare members syntactically

Parameters
l_pv1_pv1
l_pv2_pv2

Definition at line 1042 of file pointer_values_operators.c.

1043 {
1044  bool result = true;
1045 
1046  if (gen_length(l_pv1) != gen_length(l_pv2))
1047  result = false;
1048 
1049  if (result)
1050  {
1051  /* first sort lists */
1054 
1055  /* then compare members syntactically */
1056  while(result && !ENDP(l_pv1))
1057  {
1058  cell_relation pv1 = CELL_RELATION(CAR(l_pv1));
1059  cell_relation pv2 = CELL_RELATION(CAR(l_pv2));
1060 
1061  result = pv_cells_syntactically_equal_p(pv1, pv2);
1062  POP(l_pv1);
1063  POP(l_pv2);
1064  }
1065  }
1066  return result;
1067 }
int pointer_value_compare(cell_relation *ppv1, cell_relation *ppv2)
Compares two pointer values for sorting.
Definition: compare.c:255
bool pv_cells_syntactically_equal_p(cell_relation, cell_relation)
void gen_sort_list(list l, gen_cmp_func_t compare)
Sorts a list of gen_chunks in place, to avoid allocations...
Definition: list.c:796
int(* gen_cmp_func_t)(const void *, const void *)
Definition: newgen_types.h:114

References CAR, CELL_RELATION, ENDP, gen_length(), gen_sort_list(), pointer_value_compare(), POP, and pv_cells_syntactically_equal_p().

Referenced by make_simple_pv_context().

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

◆ single_pointer_assignment_to_post_pv()

void single_pointer_assignment_to_post_pv ( effect  lhs_eff,
list  l_rhs_eff,
list  l_rhs_kind,
bool  declaration_p,
list  l_in,
pv_results pv_res,
pv_context ctxt 
)

First search for all killed paths

we could be more precise/generic on abstract locations

no aliases for a newly declared entity

if lhs_eff is a may-be-killed, then all aliased effects are also may-be-killed effects

we must find in l_in all pointers p and generate p == rhs for all rhs if p is of a type compatible with rhs, and p == &*anywhere* otherwise. in fact, for the moment we generate p == &*anywhere* in all cases

dealing with first cell

not generic

not generic

generate for all alias p in l_kill p == rhs_eff

except for p==undefined or p==null (should other abstract values/locations be ignored here?)

now take kills into account

and add gen

Parameters
lhs_effhs_eff
l_rhs_eff_rhs_eff
l_rhs_kind_rhs_kind
declaration_peclaration_p
l_in_in
pv_resv_res
ctxttxt

Definition at line 1253 of file pointer_values_analyses.c.

1257 {
1258  list l_out = NIL;
1259  list l_aliased = NIL;
1260  list l_kill = NIL;
1261  list l_gen = NIL;
1262 
1263  pips_debug_effect(1, "begin for lhs_eff =", lhs_eff);
1264  pips_debug(1, "and l_rhs_eff:\n");
1265  ifdebug(1)
1266  {
1267  list l_tmp = l_rhs_kind;
1268  FOREACH(EFFECT, rhs_eff, l_rhs_eff)
1269  {
1271  pips_debug(1, "%s of:\n", cell_interpretation_value_of_p(ci)?"value": "address");
1272  pips_debug_effect(1, "\t", rhs_eff);
1273  POP(l_tmp);
1274  }
1275  }
1276  pips_debug_pvs(1, "and l_in =", l_in);
1277  bool anywhere_lhs_p = false;
1278 
1279  /* First search for all killed paths */
1280  /* we could be more precise/generic on abstract locations */
1281  if (anywhere_effect_p(lhs_eff))
1282  {
1283  pips_assert("we cannot have an anywhere lhs for a declaration\n", !declaration_p);
1284  pips_debug(3, "anywhere lhs\n");
1285  anywhere_lhs_p = true;
1286  l_kill = CONS(EFFECT, copy_effect(lhs_eff), NIL);
1287  l_aliased = l_kill;
1288  }
1289  else
1290  {
1291  if (!declaration_p) /* no aliases for a newly declared entity */
1292  {
1293  l_aliased = effect_find_aliased_paths_with_pointer_values(lhs_eff, l_in, ctxt);
1294  if (!ENDP(l_aliased) && anywhere_effect_p(EFFECT(CAR(l_aliased))))
1295  {
1296  pips_debug(3, "anywhere lhs (from aliases)\n");
1297  anywhere_lhs_p = true;
1298  l_kill = l_aliased;
1299  }
1300  else if (!ENDP(l_aliased) && ((int) gen_length(l_aliased) == 1)
1301  && (null_pointer_value_effect_p(EFFECT(CAR(l_aliased)))))
1302  {
1303  // dereferencing a null pointer is considered as undefined by the standard
1304  // with gcc (without any option) the compiler does not complain, but the execution aborts
1305  // I make the choice here that if the pointer value is exactly NULL, then
1306  // the program abort; hence there is no pointer anymore and the pointer values list is empty.
1307  pips_user_warning("null pointer is dereferenced on lhs(%s)\n",
1308  effect_to_string(lhs_eff));
1309  gen_full_free_list(l_in);
1310  l_in = NIL;
1311  l_kill = NIL;
1312  }
1313  else if (!ENDP(l_aliased) && ((int) gen_length(l_aliased) == 1)
1314  && (undefined_pointer_value_effect_p(EFFECT(CAR(l_aliased)))))
1315  {
1316  // dereferencing a non-initialized pointer is considered as undefined by the standard
1317  // However, with gcc (without any option), the compiler does not complain,
1318  // and the execution is sometimes correct.
1319  // I make the choice here that if the pointer value is (exactly) undefined
1320  // then the program does not necessarily abort;
1321  // as I can keep dereferencements in pointer values (I'm not limited
1322  // to constant paths), I still generate a kill and a gen. BC.
1323  pips_user_warning("undefined pointer is dereferenced on lhs(%s)\n",
1324  effect_to_string(lhs_eff));
1325  l_kill = CONS(EFFECT, copy_effect(lhs_eff), NIL);
1326  }
1327  else
1328  {
1329  /* if lhs_eff is a may-be-killed, then all aliased effects are also
1330  may-be-killed effects */
1331  if (effect_may_p(lhs_eff))
1332  {
1333  pips_debug(3, "may lhs effect, changing all aliased effects to may\n");
1334  effects_to_may_effects(l_aliased);
1335  }
1336  l_kill = CONS(EFFECT, copy_effect(lhs_eff), l_aliased);
1337  }
1338  }
1339  else
1340  {
1341  l_kill = CONS(EFFECT, copy_effect(lhs_eff), NIL);
1342  }
1343  }
1344 
1345  pips_debug_effects(2, "l_kill =", l_kill);
1346 
1347  if (anywhere_lhs_p)
1348  {
1349  free_pv_results_paths(pv_res);
1350  pv_res->result_paths = l_aliased;
1352 
1353  /* we must find in l_in all pointers p and generate p == rhs for all rhs if p is
1354  * of a type compatible with rhs, and p == &*anywhere* otherwise.
1355  * in fact, for the moment we generate p == &*anywhere* in all cases
1356  */
1359  FOREACH(CELL_RELATION, pv_in, l_in)
1360  {
1361  /* dealing with first cell */
1362  /* not generic */
1367 
1368  list l_gen_pv = (* ctxt->make_pv_from_effects_func)
1369  (eff_alias, anywhere_eff, rhs_kind, l_in);
1370  l_gen = (*ctxt->pvs_must_union_func)(l_gen_pv, l_gen);
1371  free_effect(eff_alias);
1372 
1376  {
1377  /* not generic */
1382 
1383  list l_gen_pv = (* ctxt->make_pv_from_effects_func)
1384  (eff_alias, anywhere_eff, rhs_kind, l_in);
1385  l_gen = (*ctxt->pvs_must_union_func)(l_gen_pv, l_gen);
1386  free_effect(eff_alias);
1387  }
1388  }
1389  free_effect(anywhere_eff);
1390  free_cell_interpretation(rhs_kind);
1391  }
1392  else
1393  {
1394  /* generate for all alias p in l_kill p == rhs_eff */
1395  /* except for p==undefined or p==null (should other abstract values/locations be ignored here?) */
1396  FOREACH(EFFECT, eff_alias, l_kill) {
1397  if (!null_pointer_value_effect_p(eff_alias)
1398  && ! undefined_pointer_value_effect_p(eff_alias))
1399  {
1400  list l_rhs_kind_tmp = l_rhs_kind;
1401  FOREACH(EFFECT, rhs_eff, l_rhs_eff)
1402  {
1403  cell_interpretation rhs_kind =
1404  CELL_INTERPRETATION(CAR(l_rhs_kind_tmp));
1405  //bool exact_preceding_p = true;
1406  list l_gen_pv = (* ctxt->make_pv_from_effects_func)
1407  (eff_alias, rhs_eff, rhs_kind, l_in);
1408  l_gen = gen_nconc(l_gen_pv, l_gen);
1409  POP(l_rhs_kind_tmp);
1410  }
1411  }
1412  }
1413  if (declaration_p)
1414  {
1415  gen_full_free_list(l_kill);
1416  l_kill = NIL;
1417  }
1418  pips_debug_pvs(2, "l_gen =", l_gen);
1419  }
1420 
1421  /* now take kills into account */
1422  l_out = kill_pointer_values(l_in, l_kill, ctxt);
1423  pips_debug_pvs(2, "l_out_after kill:", l_out);
1424 
1425  /* and add gen */
1426  l_out = (*ctxt->pvs_must_union_func)(l_out, l_gen);
1427 
1428  pv_res->l_out = l_out;
1429 
1430  return;
1431 }
void free_effect(effect p)
Definition: effects.c:451
approximation make_approximation_may(void)
Definition: effects.c:179
void free_cell_interpretation(cell_interpretation p)
Definition: effects.c:194
void effects_to_may_effects(list)
bool null_pointer_value_effect_p(effect)
bool undefined_pointer_value_effect_p(effect)
string effect_to_string(effect)
#define effect_may_p(eff)
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define pips_user_warning
Definition: misc-local.h:146
list kill_pointer_values(list, list, pv_context *)
eliminate the cells of l_kill from l_in
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

References anywhere_effect_p(), CAR, CELL_INTERPRETATION, cell_interpretation_value_of_p, CELL_RELATION, cell_relation_first_cell, cell_relation_second_cell, cell_relation_second_value_of_p, CONS, copy_cell(), copy_effect(), EFFECT, effect_find_aliased_paths_with_pointer_values(), effect_may_p, effect_to_string(), effects_to_may_effects(), ENDP, FOREACH, free_cell_interpretation(), free_effect(), free_pv_results_paths(), gen_full_free_list(), gen_length(), gen_nconc(), ifdebug, kill_pointer_values(), pv_results::l_out, make_action_write_memory(), make_anywhere_effect(), make_approximation_may(), make_cell_interpretation_address_of(), make_descriptor_none(), make_effect(), pv_context::make_pv_from_effects_func, NIL, null_pointer_value_cell_p(), null_pointer_value_effect_p(), pips_assert, pips_debug, pips_debug_effect, pips_debug_effects, pips_debug_pvs, pips_user_warning, POP, pv_context::pvs_must_union_func, pv_results::result_paths, pv_results::result_paths_interpretations, undefined_pointer_value_cell_p(), and undefined_pointer_value_effect_p().

Referenced by assignment_to_post_pv(), external_call_to_post_pv(), forloop_to_post_pv(), free_to_post_pv(), loop_to_post_pv(), multiple_pointer_assignment_to_post_pv(), safe_intrinsic_to_post_pv(), update_operator_to_post_pv(), and whileloop_to_post_pv().

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

◆ store_gen_pv()

void store_gen_pv ( statement  ,
cell_relations   
)

◆ store_kill_pv()

void store_kill_pv ( statement  ,
effects   
)

◆ store_or_update_gen_pv()

void store_or_update_gen_pv ( statement  ,
cell_relations   
)

◆ store_or_update_kill_pv()

void store_or_update_kill_pv ( statement  ,
effects   
)

◆ store_or_update_pv()

void store_or_update_pv ( statement  ,
cell_relations   
)

◆ store_pv()

void store_pv ( statement  ,
cell_relations   
)

Referenced by sequence_to_post_pv(), and statement_to_post_pv().

+ Here is the caller graph for this function:

◆ text_pv()

text text_pv ( entity  ,
int  ,
statement   
)

prettyprint.c

◆ update_gen_pv()

void update_gen_pv ( statement  ,
cell_relations   
)

◆ update_kill_pv()

void update_kill_pv ( statement  ,
effects   
)

◆ update_pv()

void update_pv ( statement  ,
cell_relations   
)

Referenced by sequence_to_post_pv(), and statement_to_post_pv().

+ Here is the caller graph for this function: