PIPS
Effects

Functions

void set_conflict_testing_properties ()
 conflicts.c More...
 
bool effects_must_conflict_p (effect eff1, effect eff2)
 Intersection tests. More...
 
bool effects_might_conflict_even_read_only_p (effect eff1, effect eff2)
 Check if two effect might conflict, even if they are read only @description Two effects may conflict if their abstract two location sets has a non-empty intersection. More...
 
bool effects_may_conflict_p (effect eff1, effect eff2)
 Check if two effect may conflict @description Two effects may conflict if their abstract two location sets has a non-empty intersection and if at least one of them is a write. More...
 
static bool old_effects_conflict_p (effect eff1, effect eff2)
 OBSOLETE, was never used !! More...
 
bool effects_conflict_p (effect eff1, effect eff2)
 Synonym for effects_may_conflict_p(). More...
 
bool array_references_may_conflict_p (list sl1, list sl2)
 Check if there may be a conflict between two array references. More...
 
bool variable_references_may_conflict_p (entity v, list sl1, list sl2)
 FIXME ? More...
 
bool references_may_conflict_p (reference r1, reference r2)
 Check if two references may conflict. More...
 
bool references_must_conflict_p (reference r1, reference r2)
 Check if two references may conflict. More...
 
static bool cells_maymust_conflict_p (cell c1, cell c2, bool must_p)
 Check if two cell may or must conflict. More...
 
bool cells_may_conflict_p (cell c1, cell c2)
 Check if two cell may conflict. More...
 
bool points_to_cell_lists_may_conflict_p (list l1, list l2)
 Same as above, but for lists. More...
 
bool cells_must_conflict_p (cell c1, cell c2)
 Check if two cell must conflict. More...
 
bool points_to_cell_lists_must_conflict_p (list l1, list l2)
 Same as above, but for lists. More...
 
bool entities_maymust_conflict_p (entity e1, entity e2, bool must_p)
 Check if two entities may or must conflict. More...
 
bool entities_may_conflict_p (entity e1, entity e2)
 Check if two entities may conflict. More...
 
bool entities_must_conflict_p (entity e1, entity e2)
 Check if two entities must conflict. More...
 
static bool first_reference_certainly_includes_second_reference_p (reference r1, reference r2)
 Inclusion tests. More...
 
static bool first_cell_certainly_includes_second_cell_p (cell c1, cell c2)
 tests whether first cell certainly includes second one More...
 
bool first_effect_certainly_includes_second_effect_p (effect eff1, effect eff2)
 tests whether first effect certainly includes second one. More...
 
bool first_exact_scalar_effect_certainly_includes_second_effect_p (effect eff1, effect eff2)
 
bool effect_may_read_or_write_memory_paths_from_entity_p (effect ef, entity e)
 misc functions More...
 
bool effects_may_read_or_write_memory_paths_from_entity_p (list l_eff, entity e)
 tests whether the input effects list may contain effects with a memory path from the input entity e; this is currently a mere syntactic test. More...
 
bool generic_effects_maymust_read_or_write_scalar_entity_p (list fx, entity e, bool must_p, bool concrete_p)
 
bool effects_maymust_read_or_write_scalar_entity_p (list fx, entity e, bool must_p)
 
bool concrete_effects_maymust_read_or_write_scalar_entity_p (list fx, entity e, bool must_p)
 
bool effects_may_read_or_write_scalar_entity_p (list fx, entity e)
 check whether scalar entity e may be read or written by effects fx or cannot be accessed at all More...
 
bool concrete_effects_may_read_or_write_scalar_entity_p (list fx, entity e)
 
bool effects_must_read_or_write_scalar_entity_p (list fx, entity e)
 check whether scalar entity e must be read or written by any effect of fx or if it simply might be accessed. More...
 
static list generic_effects_entities_which_may_conflict_with_scalar_entity (list fx, entity e, bool concrete_p)
 Returns the list of entities used in effect list fx and potentially conflicting with e. More...
 
list effects_entities_which_may_conflict_with_scalar_entity (list fx, entity e)
 
list concrete_effects_entities_which_may_conflict_with_scalar_entity (list fx, entity e)
 

Variables

static bool constant_path_effects_p = true
 Properties settings for conflict testing functions. More...
 
static bool trust_constant_path_effects_p = false
 
static bool user_effects_on_std_files_p = false
 
static bool aliasing_across_types_p = true
 
static bool aliasing_across_formal_parameters_p = false
 

Detailed Description

Function Documentation

◆ array_references_may_conflict_p()

bool array_references_may_conflict_p ( list  sl1,
list  sl2 
)

Check if there may be a conflict between two array references.

@description May the two references to array a using subscript list sl1 and sl2 access the same memory locations?

Subscript list sl1 and sl2 can be evaluated in two different stores.

It is assumed that dim(a)=length(sl1)=length(sl2);

If the nth subscript expression can be statically evaluated in both sl1 and sl2 and if the subscript values are different, there is not conflict. For instance a[i][0] does not conflict with a[j][1]. SG: this is only true if you assume no out-of-bound indices e.g int a[2][2]; a[1][0] conflict with a[0][2] ..

This is about the old references_conflict_p()

Parameters
sl1l1
sl2l2

Definition at line 276 of file conflicts.c.

276  {
277  bool conflict_p = true;
278 
279  list cind1 = list_undefined;
280  list cind2 = list_undefined;
281  for ( cind1 = sl1, cind2 = sl2; conflict_p && !ENDP(cind1) && !ENDP(cind2); POP(cind1), POP(cind2) ) {
282  expression e1 = EXPRESSION(CAR(cind1));
283  expression e2 = EXPRESSION(CAR(cind2));
284  if ( unbounded_expression_p( e1 ) || unbounded_expression_p( e2 ) )
285  conflict_p = true;
286  else {
287  intptr_t i1 = -1;
288  intptr_t i2 = -1;
289  bool i1_p = false;
290  bool i2_p = false;
291 
292  i1_p = expression_integer_value( e1, &i1 );
293  i2_p = expression_integer_value( e2, &i2 );
294  if ( i1_p && i2_p )
295  conflict_p = ( i1 == i2 );
296  else
297  conflict_p = true;
298  }
299  }
300  return conflict_p;
301 }
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
bool expression_integer_value(expression e, intptr_t *pval)
Definition: eval.c:792
bool unbounded_expression_p(expression e)
Definition: expression.c:4329
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define intptr_t
Definition: stdint.in.h:294
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References CAR, ENDP, EXPRESSION, expression_integer_value(), intptr_t, list_undefined, POP, and unbounded_expression_p().

Referenced by variable_references_may_conflict_p().

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

◆ cells_may_conflict_p()

bool cells_may_conflict_p ( cell  c1,
cell  c2 
)

Check if two cell may conflict.

Parameters
c11
c22

Definition at line 696 of file conflicts.c.

696  {
697  bool conflict_p = cells_maymust_conflict_p( c1, c2, false );
698  return conflict_p;
699 }
static bool cells_maymust_conflict_p(cell c1, cell c2, bool must_p)
Check if two cell may or must conflict.
Definition: conflicts.c:667

References cells_maymust_conflict_p().

Referenced by effects_might_conflict_even_read_only_p(), gen_may_set(), points_to_cell_lists_may_conflict_p(), and statement_with_side_effect_p().

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

◆ cells_maymust_conflict_p()

static bool cells_maymust_conflict_p ( cell  c1,
cell  c2,
bool  must_p 
)
static

Check if two cell may or must conflict.

Parameters
must_pif set to true, we enforce a must conflict

Definition at line 667 of file conflicts.c.

667  {
668  bool conflict_p = false;
671 
672  if ( cell_reference_p(c1) )
673  r1 = cell_reference(c1);
674  else if ( cell_preference_p(c1) )
676 
677  if ( cell_reference_p(c2) )
678  r2 = cell_reference(c2);
679  else if ( cell_preference_p(c2) )
681 
682  if ( reference_undefined_p(r1) || reference_undefined_p(r2) ) {
683  pips_internal_error("either undefined references or gap "
684  "not implemented yet\n");
685  }
686 
687  conflict_p = must_p ? references_must_conflict_p( r1, r2 )
688  : references_may_conflict_p( r1, r2 );
689 
690  return conflict_p;
691 }
#define cell_reference(x)
Definition: effects.h:469
#define cell_preference(x)
Definition: effects.h:472
#define cell_reference_p(x)
Definition: effects.h:467
#define cell_preference_p(x)
Definition: effects.h:470
bool references_may_conflict_p(reference r1, reference r2)
Check if two references may conflict.
Definition: conflicts.c:426
bool references_must_conflict_p(reference r1, reference r2)
Check if two references may conflict.
Definition: conflicts.c:607
#define pips_internal_error
Definition: misc-local.h:149
#define reference_undefined
Definition: ri.h:2302
#define reference_undefined_p(x)
Definition: ri.h:2303
#define preference_reference(x)
Definition: ri.h:2102

References cell_preference, cell_preference_p, cell_reference, cell_reference_p, pips_internal_error, preference_reference, reference_undefined, reference_undefined_p, references_may_conflict_p(), and references_must_conflict_p().

Referenced by cells_may_conflict_p(), and cells_must_conflict_p().

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

◆ cells_must_conflict_p()

bool cells_must_conflict_p ( cell  c1,
cell  c2 
)

Check if two cell must conflict.

Parameters
c11
c22

Definition at line 722 of file conflicts.c.

722  {
723  bool conflict_p = cells_maymust_conflict_p( c1, c2, true );
724  return conflict_p;
725 }

References cells_maymust_conflict_p().

Referenced by effects_must_conflict_p(), and points_to_cell_lists_must_conflict_p().

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

◆ concrete_effects_entities_which_may_conflict_with_scalar_entity()

list concrete_effects_entities_which_may_conflict_with_scalar_entity ( list  fx,
entity  e 
)
Parameters
fxx

Definition at line 1278 of file conflicts.c.

1279 {
1281 }
static list generic_effects_entities_which_may_conflict_with_scalar_entity(list fx, entity e, bool concrete_p)
Returns the list of entities used in effect list fx and potentially conflicting with e.
Definition: conflicts.c:1251

References generic_effects_entities_which_may_conflict_with_scalar_entity().

Referenced by precondition_intra_to_inter().

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

◆ concrete_effects_may_read_or_write_scalar_entity_p()

bool concrete_effects_may_read_or_write_scalar_entity_p ( list  fx,
entity  e 
)
Parameters
fxx

Definition at line 1220 of file conflicts.c.

1221 {
1223  return read_or_write;
1224 }
static string read_or_write(bool a)
bool concrete_effects_maymust_read_or_write_scalar_entity_p(list fx, entity e, bool must_p)
Definition: conflicts.c:1202

References concrete_effects_maymust_read_or_write_scalar_entity_p(), and read_or_write().

Referenced by generic_transformer_intra_to_inter().

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

◆ concrete_effects_maymust_read_or_write_scalar_entity_p()

bool concrete_effects_maymust_read_or_write_scalar_entity_p ( list  fx,
entity  e,
bool  must_p 
)
Parameters
fxx
must_pust_p

Definition at line 1202 of file conflicts.c.

1203 {
1204  return generic_effects_maymust_read_or_write_scalar_entity_p(fx, e, must_p, true);
1205 }
bool generic_effects_maymust_read_or_write_scalar_entity_p(list fx, entity e, bool must_p, bool concrete_p)
Definition: conflicts.c:1144

References generic_effects_maymust_read_or_write_scalar_entity_p().

Referenced by concrete_effects_may_read_or_write_scalar_entity_p().

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

◆ effect_may_read_or_write_memory_paths_from_entity_p()

bool effect_may_read_or_write_memory_paths_from_entity_p ( effect  ef,
entity  e 
)

misc functions

tests whether the input effect has a memory path from the input entity e; this is currently a mere syntactic test.

other strategies could be implemented, such as building all the memory locations reachable from "e" using generic_effect_generate_all_accessible_paths_effects_with_level, and then testing whether in the resulting effects there is an effect which may conflict with en effect from the input list. However, this would be very costly.

Parameters
eff

Definition at line 1103 of file conflicts.c.

1104 {
1105  bool read_or_write = false;
1106  if(entity_variable_p(e))
1107  {
1109  if(store_effect_p(ef) && same_entity_p(e, e_used))
1110  {
1111  read_or_write = true;
1112  }
1113  }
1114 
1115  return read_or_write;
1116 }
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
bool store_effect_p(effect)
Definition: effects.c:1062
#define entity_variable_p(e)
An entity_variable_p(e) may hide a typedef and hence a functional type.
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
#define reference_variable(x)
Definition: ri.h:2326

References effect_any_reference, entity_variable_p, read_or_write(), reference_variable, same_entity_p(), and store_effect_p().

Referenced by effects_may_read_or_write_memory_paths_from_entity_p(), and mask_effects().

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

◆ effects_conflict_p()

bool effects_conflict_p ( effect  eff1,
effect  eff2 
)

Synonym for effects_may_conflict_p().

@description Name preserved to limit rewriting of source code using the old version. Also checks results of new implementation wrt the old implementation FIXME : to be removed: was never used until now !

In general, there is no reason to have the same results... This is only a first debugging step.

Parameters
eff1ff1
eff2ff2

Definition at line 246 of file conflicts.c.

246  {
247  bool conflict_p = effects_may_conflict_p( eff1, eff2 );
248  bool old_conflict_p = old_effects_conflict_p( eff1, eff2 );
249 
250  /* In general, there is no reason to have the same results... This
251  is only a first debugging step. */
252  if ( conflict_p != old_conflict_p )
253  pips_internal_error("Inconsistent conflict detection.");
254 
255  return conflict_p;
256 }
static bool old_effects_conflict_p(effect eff1, effect eff2)
OBSOLETE, was never used !!
Definition: conflicts.c:180
bool effects_may_conflict_p(effect eff1, effect eff2)
Check if two effect may conflict @description Two effects may conflict if their abstract two location...
Definition: conflicts.c:162

References effects_may_conflict_p(), old_effects_conflict_p(), and pips_internal_error.

+ Here is the call graph for this function:

◆ effects_entities_which_may_conflict_with_scalar_entity()

list effects_entities_which_may_conflict_with_scalar_entity ( list  fx,
entity  e 
)
Parameters
fxx

Definition at line 1273 of file conflicts.c.

1274 {
1276 }

References generic_effects_entities_which_may_conflict_with_scalar_entity().

+ Here is the call graph for this function:

◆ effects_may_conflict_p()

bool effects_may_conflict_p ( effect  eff1,
effect  eff2 
)

Check if two effect may conflict @description Two effects may conflict if their abstract two location sets has a non-empty intersection and if at least one of them is a write.

This function is conservative: it is always correct to declare a conflict.

Parameters
eff1ff1
eff2ff2

Definition at line 162 of file conflicts.c.

162  {
163  action ac1 = effect_action(eff1);
164  action ac2 = effect_action(eff2);
165  bool conflict_p = true;
166 
167  if ( action_read_p(ac1) && action_read_p(ac2) ) {
168  // Two read won't conflict
169  conflict_p = false;
170  } else {
171  conflict_p = effects_might_conflict_even_read_only_p(eff1,eff2);
172  }
173  return conflict_p;
174 }
#define effect_action(x)
Definition: effects.h:642
#define action_read_p(x)
Definition: effects.h:311
bool effects_might_conflict_even_read_only_p(effect eff1, effect eff2)
Check if two effect might conflict, even if they are read only @description Two effects may conflict ...
Definition: conflicts.c:123

References action_read_p, effect_action, and effects_might_conflict_even_read_only_p().

Referenced by conflict_is_a_real_conflict_p(), effects_conflict_p(), and two_addresses_code_generator().

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

◆ effects_may_read_or_write_memory_paths_from_entity_p()

bool effects_may_read_or_write_memory_paths_from_entity_p ( list  l_eff,
entity  e 
)

tests whether the input effects list may contain effects with a memory path from the input entity e; this is currently a mere syntactic test.

other strategies could be implemented, such as building all the memory locations reachable from "e" using generic_effect_generate_all_accessible_paths_effects_with_level, and then testing whether in the resulting effects there is an effect which may conflict with en effect from the input list. However, this would be very costly.

Parameters
l_eff_eff

Definition at line 1130 of file conflicts.c.

1131 {
1132  bool read_or_write = false;
1133  if(entity_variable_p(e))
1134  {
1135  FOREACH(EFFECT, ef, l_eff)
1136  {
1138  if (read_or_write) break;
1139  }
1140  }
1141  return read_or_write;
1142 }
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
bool effect_may_read_or_write_memory_paths_from_entity_p(effect ef, entity e)
misc functions
Definition: conflicts.c:1103
#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

References EFFECT, effect_may_read_or_write_memory_paths_from_entity_p(), entity_variable_p, FOREACH, and read_or_write().

Referenced by compute_one_summary_reduction(), and compute_summary_reductions().

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

◆ effects_may_read_or_write_scalar_entity_p()

bool effects_may_read_or_write_scalar_entity_p ( list  fx,
entity  e 
)

check whether scalar entity e may be read or written by effects fx or cannot be accessed at all

In semantics, e can be a functional entity such as constant string or constant float.

Parameters
fxx

Definition at line 1214 of file conflicts.c.

1215 {
1217  return read_or_write;
1218 }
bool effects_maymust_read_or_write_scalar_entity_p(list fx, entity e, bool must_p)
Definition: conflicts.c:1197

References effects_maymust_read_or_write_scalar_entity_p(), and read_or_write().

Referenced by generic_transformer_intra_to_inter().

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

◆ effects_maymust_read_or_write_scalar_entity_p()

bool effects_maymust_read_or_write_scalar_entity_p ( list  fx,
entity  e,
bool  must_p 
)
Parameters
fxx
must_pust_p

Definition at line 1197 of file conflicts.c.

1198 {
1199  return generic_effects_maymust_read_or_write_scalar_entity_p(fx, e, must_p, false);
1200 }

References generic_effects_maymust_read_or_write_scalar_entity_p().

Referenced by effects_may_read_or_write_scalar_entity_p(), and effects_must_read_or_write_scalar_entity_p().

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

◆ effects_might_conflict_even_read_only_p()

bool effects_might_conflict_even_read_only_p ( effect  eff1,
effect  eff2 
)

Check if two effect might conflict, even if they are read only @description Two effects may conflict if their abstract two location sets has a non-empty intersection.

This function is conservative: it is always correct to declare a conflict.

For environment and type declarations, the references are empty and the conflict is only based on the referenced entity

Parameters
eff1ff1
eff2ff2

Definition at line 123 of file conflicts.c.

123  {
124  action ac1 = effect_action(eff1);
125  action ac2 = effect_action(eff2);
126  bool conflict_p = true;
127 
130 
131  if(action_kind_tag(ak1) != action_kind_tag(ak2)) {
132  // A store mutation cannot conflict with an environment or type
133  // declaration mutation
134  conflict_p = false;
135  } else {
136  if(action_kind_store_p(ak1)) {
137  cell cell1 = effect_cell(eff1);
138  cell cell2 = effect_cell(eff2);
139  if(!cells_may_conflict_p(cell1, cell2)) {
140  conflict_p = false;
141  }
142  } else {
143  /* For environment and type declarations, the references are
144  empty and the conflict is only based on the referenced
145  entity */
146  entity v1 = effect_variable(eff1);
147  entity v2 = effect_variable(eff2);
148  conflict_p = v1 == v2;
149  }
150  }
151  return conflict_p;
152 }
#define effect_variable(e)
For COMPATIBILITY purpose only - DO NOT USE anymore.
action_kind action_to_action_kind(action)
Without the consistency test, this function would certainly be inlined.
Definition: effects.c:1048
#define action_kind_tag(x)
Definition: effects.h:258
#define action_kind_store_p(x)
Definition: effects.h:259
#define effect_cell(x)
Definition: effects.h:640
bool cells_may_conflict_p(cell c1, cell c2)
Check if two cell may conflict.
Definition: conflicts.c:696

References action_kind_store_p, action_kind_tag, action_to_action_kind(), cells_may_conflict_p(), effect_action, effect_cell, and effect_variable.

Referenced by add_conflicts(), and effects_may_conflict_p().

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

◆ effects_must_conflict_p()

bool effects_must_conflict_p ( effect  eff1,
effect  eff2 
)

Intersection tests.

Check if two effects always conflict. @descriptionTwo effects will always conflict if their two abstract locations has a non-empty intersection and if at least one of them is a write. The approximation must also be "MUST", if one of them is a "MAY" there is no conflict

This function is conservative: it is always correct not to declare a conflict.

Returns
true if there is always a conflict between eff1 and eff2

We enforce must approximation for the two effects

We enforce that at least one effect is a write

Check that the cells conflicts

Parameters
eff1ff1
eff2ff2

Definition at line 93 of file conflicts.c.

93  {
94  action ac1 = effect_action(eff1);
95  action ac2 = effect_action(eff2);
98  bool conflict_p = false;
99 
100  /* We enforce must approximation for the two effects */
101  if ( approximation_exact_p(ap1) && approximation_exact_p(ap2) ) {
102  /* We enforce that at least one effect is a write */
103  if ( action_write_p(ac1) || action_write_p(ac2) ) {
104  cell cell1 = effect_cell(eff1);
105  cell cell2 = effect_cell(eff2);
106  /* Check that the cells conflicts */
107  if ( cells_must_conflict_p( cell1, cell2 ) ) {
108  conflict_p = true;
109  }
110  }
111  }
112  return conflict_p;
113 }
#define approximation_exact_p(x)
Definition: effects.h:369
#define action_write_p(x)
Definition: effects.h:314
#define effect_approximation(x)
Definition: effects.h:644
bool cells_must_conflict_p(cell c1, cell c2)
Check if two cell must conflict.
Definition: conflicts.c:722

References action_write_p, approximation_exact_p, cells_must_conflict_p(), effect_action, effect_approximation, and effect_cell.

+ Here is the call graph for this function:

◆ effects_must_read_or_write_scalar_entity_p()

bool effects_must_read_or_write_scalar_entity_p ( list  fx,
entity  e 
)

check whether scalar entity e must be read or written by any effect of fx or if it simply might be accessed.

In semantics, e can be a functional entity such as constant string or constant float.

Parameters
fxx

Definition at line 1235 of file conflicts.c.

1236 {
1238  return read_or_write;
1239 }

References effects_maymust_read_or_write_scalar_entity_p(), and read_or_write().

+ Here is the call graph for this function:

◆ entities_may_conflict_p()

bool entities_may_conflict_p ( entity  e1,
entity  e2 
)

Check if two entities may conflict.

Parameters
e11
e22

Definition at line 984 of file conflicts.c.

984  {
985  return entities_maymust_conflict_p( e1, e2, false);
986 }
bool entities_maymust_conflict_p(entity e1, entity e2, bool must_p)
Check if two entities may or must conflict.
Definition: conflicts.c:771

References entities_maymust_conflict_p().

Referenced by add_conflicts(), add_implicit_interprocedural_write_effects(), add_or_kill_equivalenced_variables(), apply_abstract_effect_to_transformer(), check_for_effected_statement(), direct_written_reference(), effects_read_variable_p(), effects_write_variable_p(), entity_may_conflict_with_a_formal_parameter_p(), find_covering_reference_path(), find_reduction_of_var(), functionnal_on_effects(), generic_effects_entities_which_may_conflict_with_scalar_entity(), generic_effects_maymust_read_or_write_scalar_entity_p(), get_effect_read_of_statement_on_variable(), get_effect_write_of_statement_on_variable(), initialize_and_verify_common_variable(), interference_on(), list_of_same_or_equivalence_arguments(), no_other_effects_on_references(), no_write_effects_on_var(), old_effects_conflict_p(), points_to_cells_intersect_p(), reference_rwt(), references_may_conflict_p(), remove_unread_variable(), there_is_a_conflict(), transformer_general_consistency_p(), update_compatible_reduction(), update_compatible_reduction_with(), update_reduction_under_effect(), value_alias(), and verify_formal_and_common_variables().

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

◆ entities_maymust_conflict_p()

bool entities_maymust_conflict_p ( entity  e1,
entity  e2,
bool  must_p 
)

Check if two entities may or must conflict.

FI->MA: we certainly said a lot more during the February 2010 meeting, when abstract locations were added. And now we have store and type declaration dependencies...

Parameters
must_pdefine if we enforce must conflict or only may one

Be careful because entity_variable_p(e) does not guarantee that e is a variable defined by the programmer. Maybe another function is needed to make sure that the conversion to an abstract location generates a useful result... variable_entity_p() is not necessarily good either because it uses the entity storage to make a decision. Formal parameters and return values are not taken into account.

There no abstract locations for formal parameters and return values, which may not be a good idea if C let you pick up the address of a formal parameter. They have to be handled in a specific way.

Beware: this function should only be used for scalar entities. however, I do not add an assert for this time, because I don't yet know what damages it may cause...

Constant strings may be tested because they are used to represent the underlying buffers. The effect should always be a read effect.

FI: Either we need an new abstract location for the formal parameters or we need to deal explictly with this case here and declare conflict with anywhere.

FIXME : variable_entity_must_conflict_p does not exist yet

A must conflict is useful to guarantee a kill, but this shows that it is not related to the definition of the may case: two variables may share exactly the same set of memory locations but a reference to one of them does not necessarily imply that all locations are read or written. More comments (thinking) are needed to distinguish between entity and reference conflicts.

We assume that e1 and e2 are program variables. Because we do not have enough comments, we do not know if this only hold for variables and arrays of one element. It is easy to argue that an array cannot must conflict with itself. The test below does not solve the case of struct, and maybe union.

FI: should always be the case here but a struct variable is a scalar, as well as the location entities representing its field. They are aliased as equivalenced Fortran variables. The case of struct and struct field can be solved at a higher level by converting effects to their location entities when it makes sense instead of relying on the effect base variable.

FI: we end up here if references linked to environment or type declarations are tested for conflicts. Should we perform such tests, basically e1==e2, or assume that they should have been handled at a higher level?

There are no conflicts between entities of different kinds

Since this implies e1!=e2, this case could be merged with the next one, but the spec would be less clear

Environment and type declaration conflicts imply that the very same entity is involved.

Parameters
e11
e22
must_pust_p

Definition at line 771 of file conflicts.c.

772 {
773  bool conflict_p = !must_p; // safe default value
774 
775  // effects package entities are not usual variables
777  conflict_p = (e1 == e2);
778  // idem with "register" variables which are in a world of their own
779  else if (entity_register_p(e1) || entity_register_p(e2))
780  conflict_p = (e1 == e2);
781  /* Constant strings may be tested because they are used to represent
782  the underlying buffers. The effect should always be a read effect. */
784  conflict_p = (e1 == e2);
785  // With location entities, we may have static aliasing in C
786  else if (!c_module_p(get_current_module_entity())) {
787  pips_debug(5, "fortran case, C case with semantics constant path analysis\n");
788  if (same_entity_p(e1, e2))
789  conflict_p = true;
790  else
791  conflict_p = must_p ? false : variable_entities_may_conflict_p( e1, e2 );
792  }
793  else if(location_entity_p(e1)) {
794  if(location_entity_p(e2)) {
795  // No aliasing between locations
796  conflict_p = e1==e2;
797  }
798  else {
801  // This entity seems to have type area and not type overloaded
802  // as expected from the lattice
803  conflict_p = !must_p;
804  }
805  else {
808  // FI: how about type_overloaded_p(t1)
809  conflict_p = !must_p && (overloaded_type_p(t2) || type_equal_p(t1, t2));
810  }
811  }
812  else {
813  value v1 = entity_initial(e1);
814  reference r1 = value_reference(v1);
815  entity ne1 = reference_variable(r1);
816  conflict_p = entities_maymust_conflict_p(ne1, e2, must_p );
817  }
818  }
819  }
820  else if(location_entity_p(e2)) {
823  // This entity seems to have type area and not type overloaded
824  // as expected from the lattice
825  conflict_p = !must_p;
826  }
827  else {
830  // FI: the type lattice should be used
831  conflict_p = !must_p && (overloaded_type_p(t1) || type_equal_p(t1, t2));
832  }
833  }
834  else {
835  value v2 = entity_initial(e2);
836  reference r2 = value_reference(v2);
837  entity ne2 = reference_variable(r2);
838  conflict_p = entities_maymust_conflict_p(e1, ne2, must_p );
839  }
840  }
841  else {
842  // these are costly function calls; call them only once.
843  bool e1_abstract_location_p = entity_abstract_location_p( e1 );
844  bool e2_abstract_location_p = entity_abstract_location_p( e2 );
845 
846  bool (*abstract_locations_conflict_p)(entity,entity);
847  abstract_locations_conflict_p =
850 
851  if (e1_abstract_location_p && e2_abstract_location_p)
852  {
853  // two abstract locations
854  conflict_p = abstract_locations_conflict_p( e1, e2 );
855  }
856  else if (e1_abstract_location_p || e2_abstract_location_p)
857  {
858  // one abstract location and a concrete one
859  entity abstract_location = e1_abstract_location_p? e1 : e2;
860  entity concrete_location = e1_abstract_location_p? e2 : e1;
861 
862  if (entity_null_locations_p(concrete_location))
863  conflict_p = entity_all_locations_p(abstract_location);
864 
865  else if ( type_variable_p(entity_basic_concrete_type(concrete_location)) )
866  {
867  if ( variable_return_p( concrete_location ) )
868  {
869  conflict_p = false;
870  }
871  else if ( entity_formal_p( concrete_location ) )
872  {
873  /* FI: Either we need an new abstract location for the formal
874  parameters or we need to deal explictly with this case
875  here and declare conflict with *anywhere*. */
876  conflict_p = entity_all_locations_p(abstract_location);
877  if(!conflict_p) {
878  entity concrete_location_al =
879  variable_to_abstract_location(concrete_location);
880  conflict_p = abstract_locations_conflict_p(abstract_location,
881  concrete_location_al);
882  }
883  }
884  else
885  {
886  entity concrete_location_al =
887  variable_to_abstract_location(concrete_location);
888  conflict_p = abstract_locations_conflict_p(abstract_location,
889  concrete_location_al);
890  }
891  }
892  else if(entity_function_p(concrete_location)) {
893  pips_internal_error("Meaningless conflict tested for function \"%s\".",
894  entity_user_name(concrete_location));
895  }
896  else
897  {
898  pips_internal_error("Unexpected case for variable \"%s\".",
899  entity_user_name(concrete_location));
900  }
901  }
902  else
903  {
904  // two concrete locations
905  if ( variable_return_p( e1 ) && variable_return_p( e2 ) )
906  {
907  conflict_p = same_entity_p(e1,e2);
908  }
909  else if ( entity_formal_p( e1 ) && entity_formal_p( e2 ) )
910  {
911  conflict_p = same_entity_p(e1,e2);
912  }
914  {
915  conflict_p = same_entity_p(e1,e2);
916  }
918  {
919  /* FIXME : variable_entity_must_conflict_p does not exist yet */
920  if( !must_p)
921  {
922  conflict_p = variable_entities_may_conflict_p( e1, e2 );
923  }
924  else
925  {
926  /* A must conflict is useful to guarantee a kill, but this
927  shows that it is not related to the definition of the
928  may case: two variables may share exactly the same set
929  of memory locations but a reference to one of them does
930  not necessarily imply that all locations are read or
931  written. More comments (thinking) are needed to
932  distinguish between entity and reference conflicts. */
933  /* We assume that e1 and e2 are program variables. Because
934  we do not have enough comments, we do not know if this
935  only hold for variables and arrays of one element. It is
936  easy to argue that an array cannot must conflict with
937  itself. The test below does not solve the case of
938  struct, and maybe union. */
939  if(entity_scalar_p(e1)) {
940  /* FI: should always be the case here but a struct
941  * variable is a scalar, as well as the location
942  * entities representing its field. They are
943  * aliased as equivalenced Fortran variables. The
944  * case of struct and struct field can be solved
945  * at a higher level by converting effects to
946  * their location entities when it makes sense
947  * instead of relying on the effect base
948  * variable. */
949  conflict_p = same_entity_p(e1,e2);
950  }
951  else
952  conflict_p = false;
953  }
954  }
955  else
956  {
957  /* FI: we end up here if references linked to environment or
958  type declarations are tested for conflicts. Should we
959  perform such tests, basically e1==e2, or assume that they
960  should have been handled at a higher level? */
961  if(!variable_entity_p(e1) || variable_entity_p(e2))
962  {
963  /* There are no conflicts between entities of different
964  kinds */
965  /* Since this implies e1!=e2, this case could be merged
966  with the next one, but the spec would be less clear */
967  conflict_p = false;
968  }
969  else {
970  /* Environment and type declaration conflicts imply that
971  the very same entity is involved. */
972  conflict_p = same_entity_p(e1,e2);
973  }
974  }
975  } // end: two concrete locations
976  }
977  return conflict_p;
978 }
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
bool entity_null_locations_p(entity e)
test if an entity is the NULL POINTER
bool entity_abstract_location_p(entity al)
bool abstract_locations_must_conflict_p(entity al1 __attribute__((__unused__)), entity al2 __attribute__((__unused__)))
Do these two abstract locations MUST share some real memory locations ? Never ! DO NOT USE THIS FUNCT...
entity variable_to_abstract_location(entity v)
returns the smallest abstract locations containing the location of variable v.
bool entity_all_locations_p(entity e)
test if an entity is the top of the lattice
bool entity_anywhere_locations_p(entity e)
test if an entity is the bottom of the lattice
bool abstract_locations_may_conflict_p(entity al1, entity al2)
Do these two abstract locations MAY share some real memory locations ?
bool constant_string_entity_p(entity e)
Definition: constant.c:356
bool location_entity_p(entity)
Definition: locations.c:349
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
int bool
we cannot use an enum or stdbool because we need to be compatible with newgen, thus boolean need to h...
Definition: newgen_types.h:78
#define false
Definition: newgen_types.h:80
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
bool entity_register_p(entity e)
Definition: entity.c:766
bool entity_formal_p(entity p)
is p a formal parameter?
Definition: entity.c:1935
bool c_module_p(entity m)
Test if a module "m" is written in C.
Definition: entity.c:2777
bool entity_function_p(entity e)
Definition: entity.c:724
bool effects_package_entity_p(entity e)
checks if an entity is an IO_EFFECTS_PACKAGE_NAME, a MALLOC_EFFECTS_NAME or a RAND_EFFECTS_PACKAGE_NA...
Definition: entity.c:1181
bool entity_scalar_p(entity)
The concrete type of e is a scalar type.
Definition: variable.c:1113
bool variable_return_p(entity)
True if a variable is the pseudo-variable used to store value returned by a function:
Definition: variable.c:1522
bool variable_entity_p(entity)
variable.c
Definition: variable.c:70
bool variable_entities_may_conflict_p(entity, entity)
Definition: size.c:689
bool type_equal_p(type, type)
Definition: type.c:547
type entity_basic_concrete_type(entity)
retrieves or computes and then returns the basic concrete type of an entity
Definition: type.c:3677
bool overloaded_type_p(type)
Returns true if t is a variable type with a basic overloaded.
Definition: type.c:2666
#define value_reference(x)
Definition: ri.h:3085
#define type_variable_p(x)
Definition: ri.h:2947
#define entity_initial(x)
Definition: ri.h:2796

References abstract_locations_may_conflict_p(), abstract_locations_must_conflict_p(), c_module_p(), constant_string_entity_p(), effects_package_entity_p(), entity_abstract_location_p(), entity_all_locations_p(), entity_anywhere_locations_p(), entity_basic_concrete_type(), entity_formal_p(), entity_function_p(), entity_initial, entity_null_locations_p(), entity_register_p(), entity_scalar_p(), entity_user_name(), false, get_current_module_entity(), location_entity_p(), overloaded_type_p(), pips_debug, pips_internal_error, reference_variable, same_entity_p(), type_equal_p(), type_variable_p, value_reference, variable_entities_may_conflict_p(), variable_entity_p(), variable_return_p(), and variable_to_abstract_location().

Referenced by entities_may_conflict_p(), and entities_must_conflict_p().

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

◆ entities_must_conflict_p()

bool entities_must_conflict_p ( entity  e1,
entity  e2 
)

Check if two entities must conflict.

Parameters
e11
e22

Definition at line 992 of file conflicts.c.

992  {
993  return entities_maymust_conflict_p( e1, e2, true);
994 }

References entities_maymust_conflict_p().

Referenced by generic_effects_maymust_read_or_write_scalar_entity_p(), references_must_conflict_p(), and remove_unread_variable().

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

◆ first_cell_certainly_includes_second_cell_p()

static bool first_cell_certainly_includes_second_cell_p ( cell  c1,
cell  c2 
)
static

tests whether first cell certainly includes second one

See also
first_effect_certainly_includes_second_effect_p

safe result

Definition at line 1026 of file conflicts.c.

1027 {
1028  bool cell1_certainly_includes_cell2_p = false; /* safe result */
1029 
1030  reference r1 = cell_to_reference(c1);
1031  reference r2 = cell_to_reference(c2);
1032 
1033  cell1_certainly_includes_cell2_p = first_reference_certainly_includes_second_reference_p(r1, r2);
1034  return cell1_certainly_includes_cell2_p;
1035 }
reference cell_to_reference(cell)
FI: probably to be moved elsewhere in ri-util.
Definition: effects.c:1326
static bool first_reference_certainly_includes_second_reference_p(reference r1, reference r2)
Inclusion tests.
Definition: conflicts.c:1010

References cell_to_reference(), and first_reference_certainly_includes_second_reference_p().

Referenced by first_effect_certainly_includes_second_effect_p(), and first_exact_scalar_effect_certainly_includes_second_effect_p().

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

◆ first_effect_certainly_includes_second_effect_p()

bool first_effect_certainly_includes_second_effect_p ( effect  eff1,
effect  eff2 
)

tests whether first effect certainly includes second one.

The effects are not necessarily functions of the same store.

This means that a[i]-exact does not necessarily contains a[i]-exact because i may not have the same value in the store to which the effects refer. This is the case for instance in the following code:

i = 1; a[i] = ...; // S1 i = 2; a[i] = ...; // S2

The assignment in S2 does not kill the assignment in S2;

This function could be improved for convex effects by eliminating from Psystems program variables which are not common inclosing loop variants. this would require much more information than what we currently have.

So in all cases, the function safely returns false for effects described with access paths which are not single entities.

safe result

Parameters
eff1ff1
eff2ff2

Definition at line 1060 of file conflicts.c.

1061 {
1062  bool eff1_certainly_includes_eff2_p = false; /* safe result */
1063 
1064  if ( effect_exact_p(eff1) && effect_scalar_p(eff1)
1065  && effect_scalar_p(eff2)
1067  {
1068  eff1_certainly_includes_eff2_p = true;
1069  }
1070 
1071  return eff1_certainly_includes_eff2_p;
1072 }
#define effect_exact_p(eff)
bool effect_scalar_p(effect)
Definition: effects.c:567
static bool first_cell_certainly_includes_second_cell_p(cell c1, cell c2)
tests whether first cell certainly includes second one
Definition: conflicts.c:1026

References effect_cell, effect_exact_p, effect_scalar_p(), and first_cell_certainly_includes_second_cell_p().

+ Here is the call graph for this function:

◆ first_exact_scalar_effect_certainly_includes_second_effect_p()

bool first_exact_scalar_effect_certainly_includes_second_effect_p ( effect  eff1,
effect  eff2 
)

safe result

Parameters
eff1ff1
eff2ff2

Definition at line 1074 of file conflicts.c.

1075 {
1076  bool eff1_certainly_includes_eff2_p = false; /* safe result */
1077 
1078  if ( effect_scalar_p(eff2)
1080  {
1081  pips_assert("the first effect is an exact and scalar effect",
1082  effect_exact_p(eff1) && effect_scalar_p(eff1));
1083  eff1_certainly_includes_eff2_p = true;
1084  }
1085 
1086  return eff1_certainly_includes_eff2_p;
1087 }
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172

References effect_cell, effect_exact_p, effect_scalar_p(), first_cell_certainly_includes_second_cell_p(), and pips_assert.

Referenced by kill_effects().

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

◆ first_reference_certainly_includes_second_reference_p()

static bool first_reference_certainly_includes_second_reference_p ( reference  r1,
reference  r2 
)
static

Inclusion tests.

I'm not sure that testing must conflicts makes much sense with sets of memory locations. We cannot well define a symmetrical semantics. However, testing the inclusion makes sense! BC. tests whether first reference certainly includes second one

See also
first_effect_certainly_includes_second_effect_p

safe result

Definition at line 1010 of file conflicts.c.

1011 {
1012  bool r1_certainly_includes_r2_p = false; /* safe result */
1013 
1016  r1_certainly_includes_r2_p = true;
1017 
1018  return r1_certainly_includes_r2_p;
1019 }
bool reference_scalar_p(reference r)
This function returns true if Reference r is scalar.
Definition: expression.c:3530

References reference_scalar_p(), reference_variable, and same_entity_p().

Referenced by first_cell_certainly_includes_second_cell_p().

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

◆ generic_effects_entities_which_may_conflict_with_scalar_entity()

static list generic_effects_entities_which_may_conflict_with_scalar_entity ( list  fx,
entity  e,
bool  concrete_p 
)
static

Returns the list of entities used in effect list fx and potentially conflicting with e.

Of course, abstract location entities do conflict with many entities, possibly of different types.

if concrete_p==true, ignore abstract location entities.

Definition at line 1251 of file conflicts.c.

1254 {
1255  list lconflict_e = NIL;
1256 
1257  FOREACH(EFFECT, ef, fx)
1258  {
1260  if(!(entity_abstract_location_p(e_used) && concrete_p))
1261  {
1262  if(entities_may_conflict_p(e, e_used))
1263  {
1264  lconflict_e = gen_nconc(lconflict_e,
1265  CONS(ENTITY, e_used, NIL));
1266  }
1267  }
1268  }
1269 
1270  return lconflict_e;
1271 }
bool entities_may_conflict_p(entity e1, entity e2)
Check if two entities may conflict.
Definition: conflicts.c:984
#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
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755

References CONS, EFFECT, effect_any_reference, entities_may_conflict_p(), ENTITY, entity_abstract_location_p(), FOREACH, gen_nconc(), NIL, and reference_variable.

Referenced by concrete_effects_entities_which_may_conflict_with_scalar_entity(), and effects_entities_which_may_conflict_with_scalar_entity().

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

◆ generic_effects_maymust_read_or_write_scalar_entity_p()

bool generic_effects_maymust_read_or_write_scalar_entity_p ( list  fx,
entity  e,
bool  must_p,
bool  concrete_p 
)

Used to be a simple pointer equality test, but now we have to cope with abstract locations.

Parameters
fxx
must_pust_p
concrete_poncrete_p

Definition at line 1144 of file conflicts.c.

1145 {
1146  bool read_or_write = false;
1147 
1148  if(location_entity_p(e)) {
1150  FOREACH(EFFECT, ef, fx) {
1152  if(must_p)
1154  else
1156  if(read_or_write)
1157  break;
1158  }
1159  }
1160  else if(entity_variable_p(e) && entity_scalar_p(e)) {
1161  FOREACH(EFFECT, ef, fx) {
1163  entity e_used = entity_undefined;
1164  if(ENDP(reference_indices(r)))
1165  e_used = reference_variable(r);
1166  else {
1167  // FI: we are in effects-util and do no know if the semantics
1168  // analysis is using or not location entities...
1169  // is r a constant memory access path ?
1171  if(entity_undefined_p(e_used))
1172  e_used = reference_variable(r);
1173  }
1174  if(!concrete_p || !entity_abstract_location_p(e_used)) {
1175  /* Used to be a simple pointer equality test, but now we have to
1176  cope with abstract locations. */
1177  if(store_effect_p(ef)) {
1178  if(must_p) {
1179  if(entity_scalar_p(e_used) && entities_must_conflict_p(e, e_used)) {
1180  read_or_write = true;
1181  break;
1182  }
1183  }
1184  else {
1185  if(entities_may_conflict_p(e, e_used)) {
1186  read_or_write = true;
1187  break;
1188  }
1189  }
1190  }
1191  }
1192  }
1193  }
1194  return read_or_write;
1195 }
entity constant_memory_access_path_to_location_entity(reference)
A constant memory access path may not be considered.
Definition: locations.c:329
bool entities_must_conflict_p(entity e1, entity e2)
Check if two entities must conflict.
Definition: conflicts.c:992
#define entity_undefined_p(x)
Definition: ri.h:2762
#define entity_undefined
Definition: ri.h:2761
#define reference_indices(x)
Definition: ri.h:2328

References constant_memory_access_path_to_location_entity(), EFFECT, effect_any_reference, ENDP, entities_may_conflict_p(), entities_must_conflict_p(), entity_abstract_location_p(), entity_initial, entity_scalar_p(), entity_undefined, entity_undefined_p, entity_variable_p, FOREACH, location_entity_p(), read_or_write(), reference_indices, reference_variable, references_may_conflict_p(), references_must_conflict_p(), store_effect_p(), and value_reference.

Referenced by concrete_effects_maymust_read_or_write_scalar_entity_p(), and effects_maymust_read_or_write_scalar_entity_p().

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

◆ old_effects_conflict_p()

static bool old_effects_conflict_p ( effect  eff1,
effect  eff2 
)
static

OBSOLETE, was never used !!

Do we point to the same area?

We do not bother with the offset and the array types

Definition at line 180 of file conflicts.c.

180  {
181  action ac1 = effect_action(eff1);
182  action ac2 = effect_action(eff2);
183  bool conflict_p = false;
184 
185  if ( action_write_p(ac1) || action_write_p(ac2) ) {
186  if ( anywhere_effect_p( eff1 ) || anywhere_effect_p( eff2 ) )
187  conflict_p = true;
188  else {
189 
190  reference r1 = effect_any_reference(eff1);
191  entity v1 = reference_variable(r1);
192  reference r2 = effect_any_reference(eff2);
193  entity v2 = reference_variable(r2);
194 
195  /* Do we point to the same area? */
196 
197  if ( entities_may_conflict_p( v1, v2 ) ) {
198  list ind1 = reference_indices(r1);
199  list ind2 = reference_indices(r2);
200  list cind1 = list_undefined;
201  list cind2 = list_undefined;
202 
203  if ( v1 != v2 ) {
204  /* We do not bother with the offset and the array types */
205  conflict_p = true;
206  } else {
207  if ( !ENDP(ind1) && !ENDP(ind2) ) {
208  for ( cind1 = ind1, cind2 = ind2; !ENDP(cind1) && !ENDP(cind2); POP(cind1), POP(cind2) ) {
209  expression e1 = EXPRESSION(CAR(cind1));
210  expression e2 = EXPRESSION(CAR(cind2));
211  if ( unbounded_expression_p( e1 ) || unbounded_expression_p( e2 ) )
212  conflict_p = true;
213  else {
214  intptr_t i1 = -1;
215  intptr_t i2 = -1;
216  bool i1_p = false;
217  bool i2_p = false;
218 
219  i1_p = expression_integer_value( e1, &i1 );
220  i2_p = expression_integer_value( e2, &i2 );
221  if ( i1_p && i2_p )
222  conflict_p = ( i1 == i2 );
223  else
224  conflict_p = true;
225  }
226  }
227  } else
228  conflict_p = true;
229  }
230  }
231 
232  else
233  conflict_p = true;
234  }
235  }
236  return conflict_p;
237 }
bool anywhere_effect_p(effect)
Is it an anywhere effect? ANYMMODULE:ANYWHERE
Definition: effects.c:346

References action_write_p, anywhere_effect_p(), CAR, effect_action, effect_any_reference, ENDP, entities_may_conflict_p(), EXPRESSION, expression_integer_value(), intptr_t, list_undefined, POP, reference_indices, reference_variable, and unbounded_expression_p().

Referenced by effects_conflict_p().

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

◆ points_to_cell_lists_may_conflict_p()

bool points_to_cell_lists_may_conflict_p ( list  l1,
list  l2 
)

Same as above, but for lists.

Lists conflict if there exist at least one element in l1 and one element in l2 that conflict.

Parameters
l11
l22

Definition at line 703 of file conflicts.c.

704 {
705  bool conflict_p = false;
706  FOREACH(CELL, c1, l1) {
707  FOREACH(CELL, c2, l2) {
708  if(cells_may_conflict_p(c1, c2)) {
709  conflict_p = true;
710  break;
711  }
712  }
713  if(conflict_p)
714  break;
715  }
716  return conflict_p;
717 }
#define CELL(x)
CELL.
Definition: effects.h:424

References CELL, cells_may_conflict_p(), and FOREACH.

Referenced by aliased_translation_p().

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

◆ points_to_cell_lists_must_conflict_p()

bool points_to_cell_lists_must_conflict_p ( list  l1,
list  l2 
)

Same as above, but for lists.

Lists conflict if there exist at least one element in l1 and one element in l2 that must conflict.

Parameters
l11
l22

Definition at line 729 of file conflicts.c.

730 {
731  bool conflict_p = false;
732  FOREACH(CELL, c1, l1) {
733  FOREACH(CELL, c2, l2) {
734  if(cells_must_conflict_p(c1, c2)) {
735  conflict_p = true;
736  break;
737  }
738  }
739  if(conflict_p)
740  break;
741  }
742  return conflict_p;
743 }

References CELL, cells_must_conflict_p(), and FOREACH.

Referenced by aliased_translation_p().

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

◆ references_may_conflict_p()

bool references_may_conflict_p ( reference  r1,
reference  r2 
)

Check if two references may conflict.

@description Can the two references r1 and r2 access the same memory location when evaluated in two different stores?

We have to deal with static aliasing for Fortran and with dynamic aliasing for C and Fortran95.

We have to deal with abstract locations used to represent sets of memory locations.

A PIPS reference is a memory access path rather than a reference as understood in programming languages:

  • a field of a struct or a union d can be accessed by subscripting d with a field number or with a field entity
  • a dereferencing is expressed by a zero subscript: *p is p[0]
  • abstract locations such as foo:HEAP or foo:HEAP**MEMORY or foo:HEAP_v3 can be used
  • heap modelization uses the malloc statement number as a subscript
  • flow-sensitive heap modelization can use indices from the surrounding loops as subscripts
  • context-sensitive heap modelization can also use function reference to record the call path

Three bool properties are involved:

  • ALIASING_ACROSS_TYPES: if false objects of different types cannot be aliased
  • ALIASING_INSIDE_DATA_STRUCTURE: if false, access paths starting from the same data structure are assumed disjoint as soon as they differ. This property holds even after pointer dereferencement. It is extremely strong and wrong for PIPS source code, unless persistant is taken into account.
  • ALIASING_ACROSS_FORMAL_PARAMETERS: if false, access paths starting from different parameters cannot conflict.

calling entities_may_conflict_p is only valid for scalar entities

here, we have either two concrete locations, one of which at least has indices, or one abstract location and one concrete location with indices. BC

I'm not completely sure of that. Are numbered heap locations considered as abstract locations? And they may have indices. Heap locations testing is a mess. BC.

FI: Can we have some dynamic aliasing?

Do we have aliasing between types?

Do we have aliasing within a data structure? This should have been checked above with variable_references_may_conflict_p(v1,ind1,ind2)

A patch for effects_package references, which cannot conflict with user variables

well, strictly speaking, couldn't they conflict with an anywhere:anywhere effect? but then there should be other conflicts...

string operations are costly - perform them only once

well type_equal_p does not perform a good job :-( BC

should ALIASING_ACROSS_DATA_STRUCTURES be also tested here?

Do we have some dereferencing in ind1 or ind2? Do we assume that p[0] conflicts with any reference? We might as well use reference_to_abstract_location()...

Could be improved with ALIASING_ACROSS_DATA_STRUCTURES?

We need to evaluate dereferencing in r2 only when a dereferencing have not been find in r1

In other words, we assume no conflict as soon as no pointer is dereferenced... even when aliasing across types is not ignored !

If aliasing across types is ignored, we know here that the two memory locations referenced are of the same type. If the pointer in one reference (let's assume only one pointer to start with) is not of type pointer to the common type, then there is no conflict.

Else, we have to assume a conflict no matter what, because simple cases should have been simplified via the points-to analysis.

Parameters
r11
r22

Definition at line 426 of file conflicts.c.

426  {
427  bool conflict_p = true; // In doubt, conflict is assumed
428  entity e1 = reference_variable(r1);
429  entity e2 = reference_variable(r2);
430  list ind1 = reference_indices(r1);
431  list ind2 = reference_indices(r2);
432  bool get_bool_property( string );
433 
435 
437  {
438  pips_debug(5, "fortran case\n");
439  if (same_entity_p(e1, e2))
440  conflict_p = variable_references_may_conflict_p( e1, ind1, ind2 );
441  else
442  conflict_p = variable_entities_may_conflict_p( e1, e2 );
443  }
444  else if (ENDP(ind1) && ENDP(ind2)) /* calling entities_may_conflict_p is only valid for scalar entities */
445  {
446  pips_debug(5, "scalar case\n");
447  conflict_p = entities_may_conflict_p( e1, e2 );
448  }
449  else
450  {
451  /* here, we have either two concrete locations, one of which at least has indices,
452  or one abstract location and one concrete location with indices. BC
453  */
454  /* I'm not completely sure of that. Are numbered heap locations considered as abstract locations?
455  And they may have indices. Heap locations testing is a mess. BC.
456  */
457 
458  // these are costly function calls; call them only once.
459  bool e1_abstract_location_p = entity_abstract_location_p( e1 );
460  bool e2_abstract_location_p = entity_abstract_location_p( e2 );
461 
462  bool e1_heap_location_p = e1_abstract_location_p
464  bool e2_heap_location_p = e2_abstract_location_p
466 
467  pips_assert("there shouldn't be two abstract locations here.",
468  !( (e1_abstract_location_p && !e1_heap_location_p)
469  && (e2_abstract_location_p && !e2_heap_location_p)));
470 
471 
472  /* FI: Can we have some dynamic aliasing? */
473  /* Do we have aliasing between types? */
474  /* Do we have aliasing within a data structure? This should have
475  been checked above with
476  variable_references_may_conflict_p(v1,ind1,ind2) */
477 
478  /* A patch for effects_package references, which cannot conflict with user variables */
479  /* well, strictly speaking, couldn't they conflict with an anywhere:anywhere effect?
480  but then there should be other conflicts... */
482  {
483  if (!same_entity_p(e1, e2) || (ENDP(ind1) && ENDP(ind2)) )
484  conflict_p = false;
485  else // same entity, with indices
486  conflict_p = variable_references_may_conflict_p( e1, ind1, ind2 );
487  }
488  else
489  {
490 
491  /* string operations are costly - perform them only once */
492  bool e1_null_p = entity_null_locations_p(e1);
493  bool e2_null_p = entity_null_locations_p(e2);
494 
495  if (e1_null_p || e2_null_p)
496  conflict_p = e1_null_p && e2_null_p;
497  else if ((e1_abstract_location_p && !e1_heap_location_p )
498  || (e2_abstract_location_p && !e2_heap_location_p ))
499  {
500  entity abstract_location_e = e1_abstract_location_p? e1: e2;
501  //entity concrete_location_e = e1_abstract_location_p? e2: e1;
502 
503  pips_debug(5, "abstract location vs. concrete location case\n");
504 
505  if (entity_all_locations_p(abstract_location_e))
506  conflict_p = true;
507  else
508  // there should be a reference_to_abstract_location function
509  // as there is a variable_to_abstract_location function
510  // assume conflict, but much more work should be done here. BC.
511  conflict_p = true;
512  }
513  else // two concrete locations
514  {
515  pips_debug(5, "two concrete locations case \n");
516  if (same_entity_p(e1, e2))
517  conflict_p = variable_references_may_conflict_p( e1, ind1, ind2 );
518  else
519  {
520  // there should be no conflict here with constant path effects
521  // however, this is still work in progress :-( and when
522  // CONSTANT_PATH_EFFECTS is set to FALSE, effects may be erroneous.
523  // so we need this to avoid over-optimistic program transformations
524 
526  {
527  conflict_p = false;
528  }
529  else
530  {
531  bool t1_to_be_freed = false, t2_to_be_freed = false;
532  type t1 = cell_reference_to_type( r1, &t1_to_be_freed );
533  type t2 = cell_reference_to_type( r2, &t2_to_be_freed );
534 
535  if ( conflict_p && !aliasing_across_types_p
536  && !type_equal_p(t1, t2) )
537  {
538  pips_debug(5, "no conflict because types are not equal\n");
539  conflict_p = false; /* well type_equal_p does not perform a good job :-( BC*/
540  }
541  if (t1_to_be_freed) free_type(t1);
542  if (t2_to_be_freed) free_type(t2);
543 
544  if ( conflict_p && !aliasing_across_formal_parameters_p
545  && entity_formal_p(e1) && entity_formal_p(e2) )
546  {
547  pips_debug(5, "no conflict because entities are formals\n");
548  conflict_p = false;
549  }
550 
551  if (conflict_p && !user_effects_on_std_files_p
552  && (std_file_entity_p(e1) || std_file_entity_p(e2)))
553  {
554  if (!same_entity_p(e1, e2))
555  conflict_p = false;
556  else
557  conflict_p = variable_references_may_conflict_p( e1, ind1, ind2 );
558  }
559 
560  /* should ALIASING_ACROSS_DATA_STRUCTURES be also tested here? */
561  if ( conflict_p )
562  {
563  /* Do we have some dereferencing in ind1 or ind2? Do we assume
564  that p[0] conflicts with any reference? We might as well use
565  reference_to_abstract_location()... */
566  /* Could be improved with ALIASING_ACROSS_DATA_STRUCTURES? */
567  bool exact;
568  // Check dereferencing in r1
569  conflict_p = effect_reference_dereferencing_p( r1, &exact );
570  if(!conflict_p) {
571  /* We need to evaluate dereferencing in r2 only when a dereferencing
572  * have not been find in r1 */
573  conflict_p = effect_reference_dereferencing_p( r2, &exact );
574  }
575  /* In other words, we assume no conflict as soon as no pointer is
576  * dereferenced... even when aliasing across types is not ignored !
577  *
578  * If aliasing across types is ignored, we know here that the
579  * two memory locations referenced are of the same type. If the
580  * pointer in one reference (let's assume only one pointer to
581  * start with) is not of type pointer to the common type, then
582  * there is no conflict.
583  *
584  * Else, we have to assume a conflict no matter what, because
585  * simple cases should have been simplified via the points-to
586  * analysis.
587  */
588  }
589 
590  }
591  }
592  } // end: two concrete locations
593 
594  }
595  }
596 
597  pips_debug(5, "there is %s may conflict\n", conflict_p? "a": "no");
598  return conflict_p;
599 }
void free_type(type p)
Definition: ri.c:2658
bool entity_flow_or_context_sentitive_heap_location_p(entity e)
bool effect_reference_dereferencing_p(reference, bool *)
Definition: type.c:233
type cell_reference_to_type(reference, bool *)
computes the type of a cell reference representing a memory access path.
Definition: type.c:466
string effect_reference_to_string(reference)
Definition: prettyprint.c:155
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
static bool user_effects_on_std_files_p
Definition: conflicts.c:64
static bool aliasing_across_formal_parameters_p
Definition: conflicts.c:66
static bool aliasing_across_types_p
Definition: conflicts.c:65
bool variable_references_may_conflict_p(entity v, list sl1, list sl2)
FIXME ?
Definition: conflicts.c:314
static bool trust_constant_path_effects_p
Definition: conflicts.c:63
static bool constant_path_effects_p
Properties settings for conflict testing functions.
Definition: conflicts.c:62
bool std_file_entity_p(entity e)
Definition: entity.c:1232

References aliasing_across_formal_parameters_p, aliasing_across_types_p, c_module_p(), cell_reference_to_type(), constant_path_effects_p, effect_reference_dereferencing_p(), effect_reference_to_string(), effects_package_entity_p(), ENDP, entities_may_conflict_p(), entity_abstract_location_p(), entity_all_locations_p(), entity_flow_or_context_sentitive_heap_location_p(), entity_formal_p(), entity_null_locations_p(), free_type(), get_bool_property(), get_current_module_entity(), pips_assert, pips_debug, reference_indices, reference_variable, same_entity_p(), std_file_entity_p(), trust_constant_path_effects_p, type_equal_p(), user_effects_on_std_files_p, variable_entities_may_conflict_p(), and variable_references_may_conflict_p().

Referenced by apply_array_effect_to_transformer(), cells_maymust_conflict_p(), do_atomize_call(), do_symbolic_tiling(), generic_effects_maymust_read_or_write_scalar_entity_p(), generic_reference_to_transformer(), and invalidate_expressions_in_statement().

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

◆ references_must_conflict_p()

bool references_must_conflict_p ( reference  r1,
reference  r2 
)

Check if two references may conflict.

@description See references_may_conflict_p

pips_user_warning("Not completely implemented yet. " "Conservative under approximation is made\n");

Check for constant subscripts

Parameters
r11
r22

Definition at line 607 of file conflicts.c.

607  {
608  bool conflict_p = false;
609  entity e1 = reference_variable(r1);
610  entity e2 = reference_variable(r2);
611 
613 
614  // Do a simple check for scalar conflicts
615  if ( reference_scalar_p( r1 ) && reference_scalar_p( r2 )
616  && entities_must_conflict_p( e1, e2 ) ) {
617  conflict_p = true;
618  } else {
619  /* pips_user_warning("Not completely implemented yet. "
620  "Conservative under approximation is made\n");*/
621  if(entities_must_conflict_p(e1, e2)) {
622  /* Check for constant subscripts */
623  list sl1 = reference_indices(r1);
624  list sl2 = reference_indices(r2);
625  int n1 = (int) gen_length(sl1);
626  int n2 = (int) gen_length(sl2);
627  if(n1==n2) {
628  list csl2 = sl2;
629  bool diff_p = false;
630  FOREACH(EXPRESSION, se1, sl1) {
631  expression se2 = EXPRESSION(CAR(csl2));
632  if(expression_equal_p(se1, se2)) {
634  ;
635  else if(expression_reference_p(se1)) {
636  reference se1r = expression_reference(se1);
637  entity se1f = reference_variable(se1r);
638  if(!entity_field_p(se1f)) {
639  diff_p = true;
640  break;
641  }
642  }
643  else {
644  diff_p = true;
645  break;
646  }
647  }
648  else {
649  diff_p = true;
650  break;
651  }
652  POP(csl2);
653  }
654  conflict_p = !diff_p;
655  }
656  }
657  }
658  pips_debug(5, "there is %s must conflict\n", conflict_p? "a": "no");
659  return conflict_p;
660 }
void const char const char const int
size_t gen_length(const list l)
Definition: list.c:150
bool entity_field_p(entity e)
e is the field of a structure
Definition: entity.c:857
bool expression_equal_p(expression e1, expression e2)
Syntactic equality e1==e2.
Definition: expression.c:1347
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
bool extended_expression_constant_p(expression exp)
Returns true if the value of the expression does not depend syntactically on the current store.
Definition: expression.c:2461

References CAR, effect_reference_to_string(), entities_must_conflict_p(), entity_field_p(), EXPRESSION, expression_equal_p(), expression_reference(), expression_reference_p(), extended_expression_constant_p(), FOREACH, gen_length(), int, pips_debug, POP, reference_indices, reference_scalar_p(), and reference_variable.

Referenced by cells_maymust_conflict_p(), and generic_effects_maymust_read_or_write_scalar_entity_p().

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

◆ set_conflict_testing_properties()

void set_conflict_testing_properties ( void  )

conflicts.c

Definition at line 68 of file conflicts.c.

69 {
70  bool get_bool_property( string );
71  constant_path_effects_p = get_bool_property("CONSTANT_PATH_EFFECTS");
72  trust_constant_path_effects_p = get_bool_property("TRUST_CONSTANT_PATH_EFFECTS_IN_CONFLICTS");
73  aliasing_across_types_p = get_bool_property( "ALIASING_ACROSS_TYPES" );
75  get_bool_property( "ALIASING_ACROSS_FORMAL_PARAMETERS" );
76  user_effects_on_std_files_p = get_bool_property("USER_EFFECTS_ON_STD_FILES");
77 }

References aliasing_across_formal_parameters_p, aliasing_across_types_p, constant_path_effects_p, get_bool_property(), trust_constant_path_effects_p, and user_effects_on_std_files_p.

Referenced by chains(), do_symbolic_tiling(), generate_two_addresses_code(), and simdizer().

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

◆ variable_references_may_conflict_p()

bool variable_references_may_conflict_p ( entity  v,
list  sl1,
list  sl2 
)

FIXME ?

@description May the two references to v using subscript list sl1 and sl2 access the same memory locations?

Subscript list sl1 and sl2 can be evaluated in two different stores.

FI: this code seems to assume that ALIASING_ACROSS_DATA_STRUCTURES is set to FALSE.

This is equivalent to a simple Fortran-like array reference

FI: this is new not really designed (!) code

Because of heap modelization functions can be used as subscript. Because of struct and union modelization, fields can be used as subscripts.

context sensitive heap modelization

assume the code is correct... Assume no floating point index... a[i] vs a[x]...

Parameters
sl1l1
sl2l2

Definition at line 314 of file conflicts.c.

315 {
316  bool conflict_p = true;
317  type t = entity_type(v);
318  int sl1n = gen_length( sl1 );
319  int sl2n = gen_length( sl2 );
321 
322  if ( sl1n == sl2n && sl1n == nd ) {
323  /* This is equivalent to a simple Fortran-like array reference */
324  conflict_p = array_references_may_conflict_p( sl1, sl2 );
325  } else {
326  if ( !ENDP(sl1) && !ENDP(sl2) ) {
327  list cind1 = list_undefined;
328  list cind2 = list_undefined;
329  /* FI: this is new not really designed (!) code */
330  for ( cind1 = sl1, cind2 = sl2; !ENDP(cind1) && !ENDP(cind2)
331  && conflict_p; POP(cind1), POP(cind2) ) {
332  expression e1 = EXPRESSION(CAR(cind1));
333  expression e2 = EXPRESSION(CAR(cind2));
334  if ( unbounded_expression_p( e1 ) || unbounded_expression_p( e2 ) )
335  conflict_p = true;
336  else if ( expression_reference_p( e1 ) && expression_reference_p( e2 ) ) {
337  /* Because of heap modelization functions can be used as
338  subscript. Because of struct and union modelization,
339  fields can be used as subscripts. */
340  entity s1 = expression_variable( e1 ); // first subscript
341  entity s2 = expression_variable( e2 ); // second subscript
342  type s1t = entity_type(s1);
343  type s2t = entity_type(s2);
344 
345  if ( type_equal_p( s1t, s2t ) ) {
346  if ( type_functional_p(s1t) ) {
347  /* context sensitive heap modelization */
348  conflict_p = same_string_p(entity_name(s1), entity_name(s2));
349  }
350  else if( entity_field_p(s1) && entity_field_p(s2))
351  {
352  if(type_struct_variable_p(t)) conflict_p=same_entity_p(s1,s2);
353  else if(type_union_variable_p(t)) conflict_p=true;
354  }
355  } else {
356  /* assume the code is correct... Assume no floating
357  point index... a[i] vs a[x]... */
358  conflict_p = false;
359  }
360  } else {
361  intptr_t i1 = -1;
362  intptr_t i2 = -1;
363  bool i1_p = false;
364  bool i2_p = false;
365 
366  i1_p = expression_integer_value( e1, &i1 );
367  i2_p = expression_integer_value( e2, &i2 );
368  if ( i1_p && i2_p )
369  conflict_p = ( i1 == i2 );
370  else
371  conflict_p = true;
372  }
373  }
374  } else
375  conflict_p = true;
376  }
377  return conflict_p;
378 }
bool array_references_may_conflict_p(list sl1, list sl2)
Check if there may be a conflict between two array references.
Definition: conflicts.c:276
#define same_string_p(s1, s2)
entity expression_variable(expression e)
Definition: expression.c:532
bool type_union_variable_p(type)
Definition: type.c:3877
bool type_struct_variable_p(type)
Definition: type.c:3867
#define type_functional_p(x)
Definition: ri.h:2950
#define type_variable(x)
Definition: ri.h:2949
#define entity_name(x)
Definition: ri.h:2790
#define variable_dimensions(x)
Definition: ri.h:3122
#define entity_type(x)
Definition: ri.h:2792
s1
Definition: set.c:247

References array_references_may_conflict_p(), CAR, ENDP, entity_field_p(), entity_name, entity_type, EXPRESSION, expression_integer_value(), expression_reference_p(), expression_variable(), gen_length(), intptr_t, list_undefined, POP, s1, same_entity_p(), same_string_p, type_equal_p(), type_functional_p, type_struct_variable_p(), type_union_variable_p(), type_variable, unbounded_expression_p(), and variable_dimensions.

Referenced by references_may_conflict_p().

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

Variable Documentation

◆ aliasing_across_formal_parameters_p

bool aliasing_across_formal_parameters_p = false
static

Definition at line 66 of file conflicts.c.

Referenced by references_may_conflict_p(), and set_conflict_testing_properties().

◆ aliasing_across_types_p

bool aliasing_across_types_p = true
static

Definition at line 65 of file conflicts.c.

Referenced by references_may_conflict_p(), and set_conflict_testing_properties().

◆ constant_path_effects_p

bool constant_path_effects_p = true
static

Properties settings for conflict testing functions.

These settings are done for performance reasons, especially in chains initial values are current default values

Definition at line 62 of file conflicts.c.

Referenced by references_may_conflict_p(), and set_conflict_testing_properties().

◆ trust_constant_path_effects_p

bool trust_constant_path_effects_p = false
static

Definition at line 63 of file conflicts.c.

Referenced by references_may_conflict_p(), and set_conflict_testing_properties().

◆ user_effects_on_std_files_p

bool user_effects_on_std_files_p = false
static

Definition at line 64 of file conflicts.c.

Referenced by references_may_conflict_p(), and set_conflict_testing_properties().