PIPS
ri_to_transformers.c File Reference
#include <stdio.h>
#include <string.h>
#include "genC.h"
#include "linear.h"
#include "misc.h"
#include "properties.h"
#include "ri.h"
#include "effects.h"
#include "ri-util.h"
#include "prettyprint.h"
#include "effects-util.h"
#include "text-util.h"
#include "effects-generic.h"
#include "effects-simple.h"
#include "pips-libs.h"
#include "transformer.h"
#include "semantics.h"
#include "c_syntax.h"
+ Include dependency graph for ri_to_transformers.c:

Go to the source code of this file.

Functions

static transformer apply_concrete_effect_to_transformer (transformer tf, effect e, expression __attribute__((unused)) rhs)
 semantical analysis More...
 
static transformer apply_abstract_effect_to_transformer (transformer tf, effect e, bool apply_p)
 
transformer apply_array_effect_to_transformer (transformer tf, effect e __attribute__((unused)), bool apply_p __attribute__((unused)))
 Effect e is assumed to be a memory write effect on an array element location. More...
 
static transformer generic_apply_effect_to_transformer (transformer tf, effect e, bool apply_p, expression rhs, bool additional_p)
 
static transformer generic_apply_effects_to_transformer (transformer tf, list el, bool apply_p, expression rhs, bool additional_p, bool abstract_p)
 These two functions are not currently used static transformer apply_effect_to_transformer(transformer tf, effect e, bool apply_p, expression rhs) { return generic_apply_effect_to_transformer(tf, e, apply_p, rhs, false); }. More...
 
static transformer apply_effects_to_transformer (transformer tf, list el, bool apply_p, expression rhs)
 
static transformer apply_additional_effects_to_transformer (transformer tf, list el, bool apply_p, expression rhs)
 
static transformer apply_abstract_effects_to_transformer (transformer tf, list el)
 
transformer effects_to_transformer (list e)
 list of effects More...
 
transformer filter_transformer (transformer t, list e)
 Previous version of effects_to_transformer() transformer effects_to_transformer(list e) { list args = NIL; Pbase b = VECTEUR_NUL; Psysteme s = sc_new();. More...
 
transformer dimensions_to_transformer (entity v, transformer pre)
 Assumes that entity_has_values_p(v) holds. More...
 
transformer declaration_to_transformer (entity v, transformer pre)
 Note: initializations of static variables are not used as transformers but to initialize the program precondition. More...
 
transformer declarations_to_transformer (list dl, transformer pre)
 For C declarations. More...
 
static transformer block_to_transformer (list b, transformer pre)
 Recursive Descent in Data Structure Statement. More...
 
list effects_to_arguments (list fx)
 list of effects More...
 
static transformer test_to_transformer (test t, transformer pre, list ef)
 effects of t More...
 
transformer intrinsic_to_transformer (entity e, list pc, transformer pre, list ef)
 effects of intrinsic call More...
 
static transformer transformer_filter_subsumed_variables (transformer tf)
 The transformer returned for a call site may be too accurate for the caller. More...
 
transformer call_to_transformer (call c, transformer pre, list ef)
 Use to be static, but may be called from expressions in C. More...
 
static transformer c_user_function_call_to_transformer (entity e, expression expr, transformer pre)
 The Fortran and C versions are about the same. More...
 
static transformer fortran_user_function_call_to_transformer (entity e, expression expr, transformer __attribute__((unused)) pre)
 its precondition More...
 
transformer user_function_call_to_transformer (entity e, expression expr, transformer pre)
 a function call is a call to a non void function in C and to a FUNCTION in Fortran More...
 
transformer generic_transformer_intra_to_inter (transformer tf, list le, bool preserve_rv_p)
 transformer translation from the module intraprocedural transformer to the module interprocedural transformer. More...
 
transformer transformer_intra_to_inter (transformer tf, list le)
 
unsigned int number_of_usable_functional_parameters (list pl)
 Number of formal parameters in pl before a vararg is reached. More...
 
transformer transformer_formal_parameter_projection (entity f, transformer t)
 
static void perform_array_element_substitutions_in_transformer (transformer tf, reference ar, reference fr, list dl, transformer prec __attribute__((unused)), bool backward_p)
 Recursive function to substitute formal and actual array elements referenced or partially referenced by ar and fr. More...
 
transformer array_elements_substitution_in_transformer (transformer tf, entity fpv, type fpt, expression e, transformer cpre __attribute__((unused)), list el __attribute__((unused)), bool backward_p)
 
transformer new_array_element_backward_substitution_in_transformer (transformer tf, entity l, reference fr, reference ar)
 Substitute formal location entity l by a location entity corresponding to ar, if it is possible. More...
 
transformer new_array_elements_backward_substitution_in_transformer (transformer tf, entity fpv, type fpt __attribute__((unused)), expression e, transformer cpre __attribute__((unused)), list el __attribute__((unused)))
 
static transformer forward_substitute_array_location_in_transformer (transformer tf, entity al, reference ar, reference alr, entity fpv)
 Compute the subscript list suffix in the abstract location reference alr with respect to the actual reference ar and use this subscript list to generate a new reference with fpv. More...
 
transformer new_array_elements_forward_substitution_in_transformer (transformer tf, entity fpv, type fpt __attribute__((unused)), expression e, transformer cpre __attribute__((unused)), list el __attribute__((unused)))
 
transformer new_array_elements_substitution_in_transformer (transformer tf, entity fpv, type fpt __attribute__((unused)), expression e, transformer cpre __attribute__((unused)), list el __attribute__((unused)), bool backward_p)
 
transformer generic_substitute_formal_array_elements_in_transformer (transformer tf, entity f, list pc, transformer pre, list ef __attribute__((unused)), bool backward_p)
 Early version. More...
 
transformer substitute_formal_array_elements_in_transformer (transformer tf, entity f, list pc, transformer pre, list ef)
 
transformer substitute_formal_array_elements_in_precondition (transformer tf, entity f, list pc, transformer pre, list ef)
 
transformer any_user_call_site_to_transformer (entity f, list pc, transformer pre, list __attribute__((unused)) ef)
 FI: the handling of varargs had to be modified for Semantics/va_arg.c. More...
 
transformer c_user_call_to_transformer (entity f, list pc, transformer pre, list ef)
 
transformer fortran_user_call_to_transformer (entity f, list pc, list ef)
 Effects are necessary to clean up the transformer t_caller. More...
 
transformer user_call_to_transformer (entity f, list pc, transformer pre, list ef)
 
transformer c_return_to_transformer (entity e __attribute__((__unused__)), list pc, list ef, transformer pre)
 FI: This transformer carry the information about the value returned, but not the fact that the next statement is not reached. More...
 
transformer assigned_expression_to_transformer (entity v, expression expr, transformer pre)
 transformer assigned_expression_to_transformer(entity e, expression expr, list ef): returns a transformer abstracting the effect of assignment "e = expr" when possible, transformer_undefined otherwise. More...
 
transformer safe_assigned_expression_to_transformer (entity v, expression expr, transformer pre)
 Always returns a fully defined transformer. More...
 
transformer integer_assign_to_transformer (expression lhs, expression rhs, transformer pre, list ef)
 This function never returns an undefined transformer. More...
 
transformer any_scalar_assign_to_transformer_without_effect (entity v, expression rhs, transformer pre)
 assign to the scalar variable v the expression rhs (a scalar variable has a basic type; it cannot be an array, a struct or a union; it can be an enum) WARNING : this function can return transformer_undefined More...
 
transformer any_scalar_assign_to_transformer (entity v, expression rhs, list ef, transformer pre)
 precondition More...
 
static transformer assign_rhs_to_cp_to_transformer (reference cp, expression rhs, transformer pre, list ef)
 
transformer transformer_apply_field_assignments_or_equalities (transformer t, reference l, reference r, type st, bool assign_p)
 For all analyzable fields f, apply the assignment "le.f = re.f;" to transformer t. More...
 
transformer transformer_apply_field_assignments (transformer t, reference l, reference r, type st)
 
transformer transformer_apply_field_equalities (transformer t, reference l, reference r, type st)
 
static transformer transformer_apply_unknown_field_assignments_or_equalities (transformer t, reference l, type st, bool assign_p)
 Simplified version of transformer_apply_field_assignments() with an unknown rhs. More...
 
transformer transformer_apply_unknown_field_assignments (transformer t, reference l, type st)
 
transformer transformer_apply_unknown_field_equalities (transformer t, reference l, type st)
 
static transformer struct_reference_assignment_or_equality_to_transformer (reference r, type t, expression rhs, transformer pre, list ef __attribute__((unused)), bool assign_p)
 
transformer struct_reference_assignment_to_transformer (reference r, type t, expression rhs, transformer pre, list ef)
 
transformer struct_reference_equality_to_transformer (reference r, type t, expression rhs, transformer pre, list ef)
 
transformer struct_variable_assignment_to_transformer (entity v, type t, expression rhs, transformer pre, list ef)
 
transformer struct_variable_equality_to_transformer (entity v, type t, expression rhs, transformer pre, list ef)
 
static transformer assign_rhs_to_reflhs_to_transformer (reference rlhs, expression rhs, transformer pre, list ef)
 
transformer any_assign_to_transformer (list args, list ef, transformer pre)
 precondition More...
 
static transformer update_cp_with_rhs_to_transformer (reference __attribute__((unused)) cp, expression __attribute__((unused)) rhs, transformer __attribute__((unused)) pre, list __attribute__((unused)) ef)
 see assign_rhs_to_cp_to_transformer and update_reflhs_with_rhs_to_transformer to make update_cp_with_rhs_to_transformer More...
 
static transformer update_reflhs_with_rhs_to_transformer (entity op, reference rlhs, expression rhs, transformer pre, list ef)
 
transformer any_update_to_transformer (entity op, list args, list ef, transformer pre)
 precondition More...
 
static transformer basic_update_reflhs_with_rhs_to_transformer (entity op, reference rlhs, expression rhs, transformer pre, list ef)
 
transformer any_basic_update_to_transformer (entity op, list args, list ef, transformer pre)
 precondition More...
 
static transformer instruction_to_transformer (instruction i, transformer pre, list e)
 effects associated to instruction i More...
 
transformer complete_statement_transformer (transformer t, transformer pre, statement s)
 Returns the effective transformer ct for a given statement s. More...
 
transformer complete_non_identity_statement_transformer (transformer t, transformer pre, statement s)
 FI: only implemented for while loops. More...
 
transformer generic_complete_statement_transformer (transformer t, transformer pre, statement s, bool identity_p)
 Loops, do, for, while or repeat, have transformers linked to their body preconditions so as to compute those. More...
 
transformer statement_to_transformer (statement s, transformer spre)
 stmt precondition More...
 

Function Documentation

◆ any_assign_to_transformer()

transformer any_assign_to_transformer ( list  args,
list  ef,
transformer  pre 
)

precondition

The lhs must be a scalar reference to perform an interesting analysis in Fortran. In C, the condition can be relaxed to take into account side effects in sub-expressions.

f ou NIL ??

if some condition was not met and transformer derivation failed

Parameters
argsrgs
efarguments for assign
preeffects of assign

Definition at line 3177 of file ri_to_transformers.c.

3180 {
3182  expression lhs = EXPRESSION(CAR(args));
3183  expression rhs = EXPRESSION(CAR(CDR(args)));
3184  // Take care of side effects in lhs
3185  // FI: do you want to take care of the write effect as well ?
3186 
3187  // The false read implied here does not matter because only write
3188  // effects are taken into account
3190  // FI: the rhs should be evaluated first according to the C standard
3191  transformer npre = transformer_apply(lhst, pre);
3192  // How about the side effects in rhs? It might be done below?
3193  // transformer trhs = safe_expression_to_transformer(rhs, npre);
3194  // transformer nnpre = transformer_apply(lhsr, npre);
3195  // Side-effects transformer setf
3196  // transformer seft = transformer_combine(rhst, lhst);
3197  // free_transformer(lhst); // rhst is propagated as seft
3198  // free_transformer(npre);
3199 
3200  pips_assert("2 args to assign", CDR(CDR(args))==NIL);
3201 
3202  syntax slhs = expression_syntax(lhs);
3203  /* The lhs must be a scalar reference to perform an interesting
3204  analysis in Fortran. In C, the condition can be relaxed to take
3205  into account side effects in sub-expressions. */
3206  if(syntax_reference_p(slhs)) {
3207  reference rlhs = syntax_reference(slhs);
3208  // FI: it is assumed that lhst is identity in case lhs is a reference
3209  // that leads to a defined transformer
3210  // Range of the new precondition: nprer
3211  // transformer nprer = transformer_range(npre);
3212  tf = assign_rhs_to_reflhs_to_transformer(rlhs, rhs, pre, ef);
3213  //free_transformer(nprer);
3214  }
3215  // case constant path in lhs (dereferencing, struct, array)
3216  else if (syntax_call_p(slhs) || syntax_subscript_p(slhs)) {
3219  int n = (int) gen_length(l);
3220  // FI: I wonder what happens with side effects in the rhs and
3221  // with pointer dereferencing in the rhs
3222  FOREACH(CELL, cp, l) {
3224 
3225  // example of case which is normally filter *p when p formal
3226  // parameter, or dynamic allocation of p
3228  && analyzed_reference_p(rlhs)) {
3229  ifdebug(7) {
3230  pips_debug(7, "source reference : %s\n", reference_to_string(rlhs));
3231  }
3232 
3233  transformer rt = assign_rhs_to_reflhs_to_transformer(rlhs, rhs, npre, ef/*ef ou NIL ?? */);
3234  // NL : It must have be a better way to do that but I don't know how
3235  if (transformer_undefined_p(tf))
3236  tf = rt;
3237  else {
3238  if(transformer_undefined_p(rt)) {
3239  // FI: absorbing element
3240 
3241  // FI: this is not going to work in general, because
3242  // undefined is used to perform or not the convex hull
3243  tf = transformer_undefined;
3244  }
3245  else {
3246  tf = transformer_convex_hull(tf, rt);
3247  free_transformer(rt);
3248  }
3249  }
3250  }
3251  else if(anywhere_reference_p(rlhs)) {
3252  /*
3253  list nefl = CONS(EFFECT, anywhere_effect(make_action_write_memory()), NIL);
3254  tf = effects_to_transformer(nefl);
3255  gen_full_free_list(nefl);
3256  */
3257  tf = transformer_undefined;
3258  }
3259  else if(reference_typed_anywhere_locations_p(rlhs)) {
3260  /*
3261  type t = points_to_reference_to_concrete_type(rlhs);
3262  cell c = make_anywhere_points_to_cell(t);
3263  effect nef = make_effect(c, make_action_write_memory(),
3264  make_approximation_may(), make_descriptor_none());
3265  list nefl = CONS(EFFECT, nef, NIL);
3266  tf = effects_to_transformer(nefl);
3267  gen_full_free_list(nefl);
3268  */
3269  tf = transformer_undefined;
3270  }
3271  }
3272  }
3273  }
3274  else {
3275  // if nothing else retrieve lhs and rhs transformers
3276  transformer rhst = safe_expression_to_transformer(rhs, npre);
3277  // transformer nnpre = transformer_apply(lhsr, npre);
3278  // Side-effects transformer setf
3279  tf = transformer_combine(rhst, lhst);
3280  // free_transformer(lhst); // rhst is propagated as seft, done below
3281  // free_transformer(npre); // done below
3282  tf = apply_additional_effects_to_transformer(tf, ef, true, rhs);
3283  }
3284 
3285  free_transformer(npre);
3286 
3287  /* if some condition was not met and transformer derivation failed */
3288  // This should be dead code now
3289  if(tf==transformer_undefined) {
3290  transformer tf1 = lhst;
3292  tf = transformer_combine (tf1, tf2);
3293  free_transformer(tf2); // tf1 is exported in tf
3294  // FI: previous solution, only based on effects, was much safer
3295  // and simpler ! But kills tf1 and tf2 by definition... tf =
3296  // apply_effects_to_transformer(tf, ef, true, rhs); FI: the all
3297  // assignment should be passed as expression to provide
3298  // information about the effects origin: make_binary_call(=, lhs,
3299  // rhs); lhs is more likely than rhs to explain the effects
3300  tf = apply_additional_effects_to_transformer(tf, ef, true, lhs);
3301  }
3302  else {
3303  free_transformer(lhst);
3304  }
3305 
3306  pips_debug(6,"return tf=%p\n", tf);
3307  ifdebug(6) (void) print_transformer(tf);
3308  pips_debug(6,"end\n");
3309  return tf;
3310 }
void free_transformer(transformer p)
Definition: ri.c:2616
bool reference_typed_anywhere_locations_p(reference r)
test if a reference is the bottom of the lattice
void const char const char const int
reference cell_any_reference(cell)
API for reference.
Definition: effects.c:77
bool anywhere_reference_p(reference)
Definition: effects.c:378
bool pt_to_list_undefined_p(void)
points_to.c
#define CELL(x)
CELL.
Definition: effects.h:424
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
size_t gen_length(const list l)
Definition: list.c:150
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
string reference_to_string(reference r)
Definition: expression.c:87
#define print_transformer(t)
Definition: print.c:357
#define syntax_reference_p(x)
Definition: ri.h:2728
#define transformer_undefined
Definition: ri.h:2847
#define transformer_undefined_p(x)
Definition: ri.h:2848
#define syntax_reference(x)
Definition: ri.h:2730
#define syntax_call_p(x)
Definition: ri.h:2734
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define expression_undefined
Definition: ri.h:1223
#define expression_syntax(x)
Definition: ri.h:1247
#define syntax_subscript_p(x)
Definition: ri.h:2743
static transformer assign_rhs_to_reflhs_to_transformer(reference rlhs, expression rhs, transformer pre, list ef)
static transformer apply_additional_effects_to_transformer(transformer tf, list el, bool apply_p, expression rhs)
Pvecteur cp
pointeur sur l'egalite ou l'inegalite courante
Definition: sc_read.c:87
bool semantics_usable_points_to_reference_p(reference rlhs, expression lhs, int n)
See if references rlhs is usable and process null, undefined and anywhere locations defined by rlhs.
Definition: expression.c:6194
transformer safe_expression_to_transformer(expression exp, transformer pre)
Definition: expression.c:5307
list semantics_expression_to_points_to_sources(expression e)
Special wrapping for the semantics analyses.
Definition: points_to.c:94
#define ifdebug(n)
Definition: sg.c:47
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
transformer transformer_convex_hull(transformer t1, transformer t2)
transformer transformer_convex_hull(t1, t2): compute convex hull for t1 and t2; t1 and t2 are slightl...
Definition: convex_hull.c:216
transformer transformer_combine(volatile transformer t1, transformer t2)
transformer transformer_combine(transformer t1, transformer t2): compute the composition of transform...
Definition: transformer.c:238
transformer transformer_apply(transformer tf, transformer pre)
transformer transformer_apply(transformer tf, transformer pre): apply transformer tf on precondition ...
Definition: transformer.c:1559
bool analyzed_reference_p(reference)
FI: Nelson explains the motivation for can_be_constant_path_p() but I do not understand them.
Definition: value.c:518
bool constant_path_analyzed_p(void)
Definition: value.c:330

References analyzed_reference_p(), anywhere_reference_p(), apply_additional_effects_to_transformer(), assign_rhs_to_reflhs_to_transformer(), CAR, CDR, CELL, cell_any_reference(), constant_path_analyzed_p(), cp, EXPRESSION, expression_syntax, expression_undefined, FOREACH, free_transformer(), gen_length(), ifdebug, int, NIL, pips_assert, pips_debug, print_transformer, pt_to_list_undefined_p(), reference_to_string(), reference_typed_anywhere_locations_p(), safe_expression_to_transformer(), semantics_expression_to_points_to_sources(), semantics_usable_points_to_reference_p(), syntax_call_p, syntax_reference, syntax_reference_p, syntax_subscript_p, transformer_apply(), transformer_combine(), transformer_convex_hull(), transformer_undefined, and transformer_undefined_p.

Referenced by intrinsic_to_transformer(), and intrinsic_to_transformer_list().

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

◆ any_basic_update_to_transformer()

transformer any_basic_update_to_transformer ( entity  op,
list  args,
list  ef,
transformer  pre 
)

precondition

The lhs must be a scalar reference to perform an interesting analysis No more, lhs can also be dereferencing

f ou NIL ??

if some condition was not met and transformer derivation failed

Parameters
opp
argsrgs
efarguments for update
preeffects of assign

Definition at line 3525 of file ri_to_transformers.c.

3529 {
3531  expression lhs = EXPRESSION(CAR(args));
3532  syntax slhs = expression_syntax(lhs);
3533 
3534  pips_assert("1 arg for basic_update", CDR(args)==NIL);
3535 
3536  ifdebug(8) (void) print_expression(lhs);
3537 
3538  /* The lhs must be a scalar reference to perform an interesting analysis
3539  * No more, lhs can also be dereferencing
3540  */
3541  if(syntax_reference_p(slhs)) {
3542  reference rlhs = syntax_reference(slhs);
3543  tf = basic_update_reflhs_with_rhs_to_transformer(op, rlhs, lhs, pre, ef);
3544  }
3545  // case constant path in lhs (dereferencing, struct, array)
3546  else if (syntax_call_p(slhs)) {
3547  if (!pt_to_list_undefined_p()) {
3549  FOREACH(CELL, cp, l) {
3551 
3552  // example of case which is normally filter *p when p formal parameter, or dynamic allocation of p
3553  if (analyzed_reference_p(rlhs)) {
3554  entity source_lhs = reference_variable(rlhs);
3555 
3556  ifdebug(7) {
3557  pips_debug(7, "source reference : %s\n", reference_to_string(rlhs));
3558  }
3559 
3560  if (entity_null_locations_p(source_lhs)) {
3561  if (gen_length(l) == 1)
3562  pips_user_error("The pointer \"%s\" points to NULL\n", expression_to_string(lhs));
3563  else
3564  semantics_user_warning("The pointer \"%s\" can point to NULL\n", expression_to_string(lhs));
3565  } else if (entity_typed_nowhere_locations_p(source_lhs)) {
3566  if (gen_length(l) == 1)
3567  pips_user_error("The pointer %s points to undefined/indeterminate (%s)\n", expression_to_string(lhs), reference_to_string(rlhs));
3568  else
3569  semantics_user_warning("The pointer %s can points to undefined/indeterminate (%s)\n", expression_to_string(lhs), reference_to_string(rlhs));
3570  }
3571  else {
3572  // can be improve with a specific function
3573  // we will compute 2 times the path to find the cp
3574  // see assign_rhs_to_cp_to_transformer or update_cp_with_rhs_to_transformer to make basic_update_cp_with_rhs_to_transformer
3575  transformer rt = basic_update_reflhs_with_rhs_to_transformer(op, rlhs, lhs, pre, ef/*ef ou NIL ?? */);
3576  // NL : It must have be a better way to do that but I don't know how
3577  if (transformer_undefined_p(tf))
3578  tf = rt;
3579  else {
3580  tf = transformer_convex_hull(tf, rt);
3581  free_transformer(rt);
3582  }
3583  }
3584  }
3585  }
3586  }
3587  }
3588 
3589  /* if some condition was not met and transformer derivation failed */
3590  if(tf==transformer_undefined)
3591  tf = effects_to_transformer(ef);
3592 
3593  pips_debug(6,"return tf=%p\n", tf);
3594  ifdebug(6) (void) print_transformer(tf);
3595  pips_debug(8,"end\n");
3596  return tf;
3597 }
bool entity_null_locations_p(entity e)
test if an entity is the NULL POINTER
bool entity_typed_nowhere_locations_p(entity e)
test if an entity is the bottom of the lattice
#define cell_reference(x)
Definition: effects.h:469
#define cell_preference(x)
Definition: effects.h:472
#define cell_preference_p(x)
Definition: effects.h:470
#define pips_user_error
Definition: misc-local.h:147
void print_expression(expression e)
no file descriptor is passed to make is easier to use in a debugging stage.
Definition: expression.c:58
string expression_to_string(expression e)
Definition: expression.c:77
#define reference_variable(x)
Definition: ri.h:2326
#define preference_reference(x)
Definition: ri.h:2102
static transformer basic_update_reflhs_with_rhs_to_transformer(entity op, reference rlhs, expression rhs, transformer pre, list ef)
transformer effects_to_transformer(list e)
list of effects
#define semantics_user_warning

References analyzed_reference_p(), basic_update_reflhs_with_rhs_to_transformer(), CAR, CDR, CELL, cell_preference, cell_preference_p, cell_reference, cp, effects_to_transformer(), entity_null_locations_p(), entity_typed_nowhere_locations_p(), EXPRESSION, expression_syntax, expression_to_string(), FOREACH, free_transformer(), gen_length(), ifdebug, NIL, pips_assert, pips_debug, pips_user_error, preference_reference, print_expression(), print_transformer, pt_to_list_undefined_p(), reference_to_string(), reference_variable, semantics_expression_to_points_to_sources(), semantics_user_warning, syntax_call_p, syntax_reference, syntax_reference_p, transformer_convex_hull(), transformer_undefined, and transformer_undefined_p.

Referenced by intrinsic_to_transformer(), and intrinsic_to_transformer_list().

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

◆ any_scalar_assign_to_transformer()

transformer any_scalar_assign_to_transformer ( entity  v,
expression  rhs,
list  ef,
transformer  pre 
)

precondition

Parameters
rhshs
eff
preeffects of assign

Definition at line 2832 of file ri_to_transformers.c.

2836 {
2838 
2839  if(transformer_undefined_p(tf))
2840  tf = effects_to_transformer(ef);
2841 
2842  return tf;
2843 }
transformer any_scalar_assign_to_transformer_without_effect(entity v, expression rhs, transformer pre)
assign to the scalar variable v the expression rhs (a scalar variable has a basic type; it cannot be ...

References any_scalar_assign_to_transformer_without_effect(), effects_to_transformer(), and transformer_undefined_p.

Referenced by add_loop_index_initialization(), any_assign_to_transformer_list(), any_basic_update_to_transformer_list(), any_update_to_transformer_list(), assign_rhs_to_cp_to_transformer(), assign_rhs_to_reflhs_to_transformer(), basic_update_reflhs_with_rhs_to_transformer(), loop_initialization_to_transformer(), and update_reflhs_with_rhs_to_transformer().

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

◆ any_scalar_assign_to_transformer_without_effect()

transformer any_scalar_assign_to_transformer_without_effect ( entity  v,
expression  rhs,
transformer  pre 
)

assign to the scalar variable v the expression rhs (a scalar variable has a basic type; it cannot be an array, a struct or a union; it can be an enum) WARNING : this function can return transformer_undefined

Parameters
ventity/variable to be assign
rhsexpression/value to assign
preprecondition, transformer already present
Returns
transformer_undefined or transformer with the scalar assignment precondition

Is it standard compliant? The assigned variable is modified by the rhs.

Take care of aliasing

tf = transformer_value_substitute(tf, v_new, v_old);

Parameters
rhshs
prere

Definition at line 2766 of file ri_to_transformers.c.

2769 {
2771 
2772  if(entity_has_values_p(v)) {
2773  entity v_new = entity_to_new_value(v);
2774  entity v_old = entity_to_old_value(v);
2776 
2777  tf = any_expression_to_transformer(tmp, rhs, pre, true);
2778 
2779  if(!transformer_undefined_p(tf)) {
2780 
2781  ifdebug(8) {
2782  pips_debug(8, "A transformer has been obtained:\n");
2783  dump_transformer(tf);
2784  }
2785 
2787  /* Is it standard compliant? The assigned variable is modified by the rhs. */
2788  transformer teq = simple_equality_to_transformer(v, tmp, true);
2789  string s = expression_to_string(rhs);
2790 
2791  semantics_user_warning("Variable \"%s\" in lhs is uselessly or "
2792  "illegally updated by rhs '%s'\n",
2793  entity_user_name(v), s);
2794  // entity_local_name(v), s);
2795 
2796  free(s);
2797 
2798  tf = transformer_combine(tf, teq);
2799  free_transformer(teq);
2800  }
2801  else {
2802  /* Take care of aliasing */
2803  entity v_repr = value_to_variable(v_new);
2804 
2805  /* tf = transformer_value_substitute(tf, v_new, v_old); */
2806  tf = transformer_value_substitute(tf, v_new, v_old);
2807 
2808  pips_debug(8,"After substitution v_new=%s -> v_old=%s\n",
2809  entity_local_name(v_new), entity_local_name(v_old));
2810  ifdebug(8) dump_transformer(tf);
2811 
2812  tf = transformer_value_substitute(tf, tmp, v_new);
2813 
2814  pips_debug(8,"After substitution tmp=%s -> v_new=%s\n",
2815  entity_local_name(tmp), entity_local_name(v_new));
2816  ifdebug(8) dump_transformer(tf);
2817 
2819  }
2820  }
2821  if(!transformer_undefined_p(tf)) {
2823  pips_debug(8, "After temporary value projection, tf=%p:\n", tf);
2824  ifdebug(8) dump_transformer(tf);
2825  }
2827  }
2828 
2829  return tf;
2830 }
bool entity_is_argument_p(entity e, cons *args)
Definition: arguments.c:150
transformer transformer_add_modified_variable(transformer tf, entity var)
FI: this function does not end up with a consistent transformer because the old value is not added to...
Definition: basic.c:889
if(!(yy_init))
Definition: genread_lex.c:1029
void free(void *)
#define dump_transformer(t)
Definition: print.c:355
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
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
type ultimate_type(type)
Definition: type.c:3466
#define transformer_arguments(x)
Definition: ri.h:2871
#define entity_type(x)
Definition: ri.h:2792
transformer any_expression_to_transformer(entity v, expression expr, transformer pre, bool is_internal)
A set of functions to compute the transformer associated to an expression evaluated in a given contex...
Definition: expression.c:4993
return(s1)
transformer transformer_value_substitute(transformer t, entity e1, entity e2)
transformer transformer_value_substitute(transformer t, entity e1, entity e2): if e2 does not appear ...
Definition: transformer.c:1993
transformer transformer_temporary_value_projection(transformer tf)
Definition: transformer.c:1149
transformer simple_equality_to_transformer(entity e, entity f, bool assignment)
e and f are assumed to be values, Type independent.
Definition: transformer.c:58
entity make_local_temporary_value_entity(type)
Definition: value.c:605
entity entity_to_new_value(entity)
Definition: value.c:859
void reset_temporary_value_counter(void)
Definition: value.c:250
bool entity_has_values_p(entity)
This function could be made more robust by checking the storage of e.
Definition: value.c:911
entity entity_to_old_value(entity)
Definition: value.c:869
entity value_to_variable(entity)
Get the primitive variable associated to any value involved in a transformer.
Definition: value.c:1624

References any_expression_to_transformer(), dump_transformer, entity_has_values_p(), entity_is_argument_p(), entity_local_name(), entity_to_new_value(), entity_to_old_value(), entity_type, entity_user_name(), expression_to_string(), free(), free_transformer(), ifdebug, make_local_temporary_value_entity(), pips_debug, reset_temporary_value_counter(), semantics_user_warning, simple_equality_to_transformer(), transformer_add_modified_variable(), transformer_arguments, transformer_combine(), transformer_temporary_value_projection(), transformer_undefined, transformer_undefined_p, transformer_value_substitute(), ultimate_type(), and value_to_variable().

Referenced by any_scalar_assign_to_transformer().

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

◆ any_update_to_transformer()

transformer any_update_to_transformer ( entity  op,
list  args,
list  ef,
transformer  pre 
)

precondition

The lhs must be a scalar reference to perform an interesting analysis No more, lhs can also be dereferencing

f ou NIL ??

if some condition was not met and transformer derivation failed

Parameters
opp
argsrgs
efarguments for update
preeffects of assign

Definition at line 3401 of file ri_to_transformers.c.

3405 {
3407  expression lhs = EXPRESSION(CAR(args));
3408  expression rhs = EXPRESSION(CAR(CDR(args)));
3409  syntax slhs = expression_syntax(lhs);
3410 
3411  pips_assert("2 args for regular update", CDR(CDR(args))==NIL);
3412 
3413  /* The lhs must be a scalar reference to perform an interesting analysis
3414  * No more, lhs can also be dereferencing
3415  */
3416  if(syntax_reference_p(slhs)) {
3417  reference rlhs = syntax_reference(slhs);
3418  tf = update_reflhs_with_rhs_to_transformer(op, rlhs, rhs, pre, ef);
3419  }
3420  // case constant path in lhs (dereferencing, struct, array)
3421  else if (syntax_call_p(slhs)) {
3422  if (!pt_to_list_undefined_p()) {
3424  FOREACH(CELL, cp, l) {
3426 
3427  // example of case which is normally filter *p when p formal parameter, or dynamic allocation of p
3428  if (analyzed_reference_p(rlhs)) {
3429  entity source_lhs = reference_variable(rlhs);
3430 
3431  ifdebug(7) {
3432  pips_debug(7, "source reference : %s\n", reference_to_string(rlhs));
3433  }
3434 
3435  if (entity_null_locations_p(source_lhs)) {
3436  if (gen_length(l) == 1)
3437  pips_user_error("The pointer %s points to NULL\n", expression_to_string(lhs));
3438  else
3439  semantics_user_warning("The pointer %s can points to NULL\n", expression_to_string(lhs));
3440  } else if (entity_typed_nowhere_locations_p(source_lhs)) {
3441  if (gen_length(l) == 1)
3442  pips_user_error("The pointer %s points to undefined/indeterminate (%s)\n", expression_to_string(lhs), reference_to_string(rlhs));
3443  else
3444  semantics_user_warning("The pointer %s can points to undefined/indeterminate (%s)\n", expression_to_string(lhs), reference_to_string(rlhs));
3445  }
3446  else {
3447  transformer rt = update_reflhs_with_rhs_to_transformer(op, rlhs, rhs, pre, ef/*ef ou NIL ?? */);
3448  // NL : It must have be a better way to do that but I don't know how
3449  if (transformer_undefined_p(tf))
3450  tf = rt;
3451  else {
3452  tf = transformer_convex_hull(tf, rt);
3453  free_transformer(rt);
3454  }
3455  }
3456  }
3457  }
3458  }
3459  }
3460 
3461  /* if some condition was not met and transformer derivation failed */
3462  if(tf==transformer_undefined)
3463  tf = effects_to_transformer(ef);
3464 
3465  pips_debug(6,"return tf=%p\n", tf);
3466  ifdebug(6) (void) print_transformer(tf);
3467  pips_debug(8,"end\n");
3468  return tf;
3469 }
static transformer update_reflhs_with_rhs_to_transformer(entity op, reference rlhs, expression rhs, transformer pre, list ef)

References analyzed_reference_p(), CAR, CDR, CELL, cell_preference, cell_preference_p, cell_reference, cp, effects_to_transformer(), entity_null_locations_p(), entity_typed_nowhere_locations_p(), EXPRESSION, expression_syntax, expression_to_string(), FOREACH, free_transformer(), gen_length(), ifdebug, NIL, pips_assert, pips_debug, pips_user_error, preference_reference, print_transformer, pt_to_list_undefined_p(), reference_to_string(), reference_variable, semantics_expression_to_points_to_sources(), semantics_user_warning, syntax_call_p, syntax_reference, syntax_reference_p, transformer_convex_hull(), transformer_undefined, transformer_undefined_p, and update_reflhs_with_rhs_to_transformer().

Referenced by intrinsic_to_transformer(), and intrinsic_to_transformer_list().

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

◆ any_user_call_site_to_transformer()

transformer any_user_call_site_to_transformer ( entity  f,
list  pc,
transformer  pre,
list __attribute__((unused))  ef 
)

FI: the handling of varargs had to be modified for Semantics/va_arg.c.

The code should probably now be refactored.

This function only creates the relations implied by the binding of formal parameters passed by value, that is all but arrays, and actual parameters.

Formal parameters are counted 1, 2, 3,...

AX_INT

Maximal numer of actual arguments that can be used.

This may happen with a void declaration

This may happen with a varargs: the number of actual arguments is greater than or equal to the number of formal parameters

FI: this case could be processed...

The first actual arguments can be used

Evaluate actual arguments from left to right linking it to a functional parameter when possible

Because we are using the caller's framework, we cannot use the new/old value naming in the callee's framework

entity fpvv = entity_to_new_value(fpv);

Let's cheat: we know fpvv would be fpv. Furthermore, the formal parameter cannot be updated in C because of the value passing mode.

FI: we could accept a number of actual parameters greater than the number of formal parameters and move on by ignoring expression e?!? Side effects in e should be taken into account anyway...

FI: Let's assume it is an enum derived type... Too late for a better job...

The associated transformer may nevertheless carry useful/necessary information

Can we still use the next actual parameter? Maybe not because of a vararg.

Definition at line 2026 of file ri_to_transformers.c.

2030 {
2035  functional fft = type_functional(ft); // proper assert checked earlier
2036  list pl = functional_parameters(fft);
2037  // To deal with void and varargs
2038  unsigned int pll = number_of_usable_functional_parameters(pl);
2039  list cpl = pl; // to simplify debugging
2040  int n = 1; /* Formal parameters are counted 1, 2, 3,...*/
2041  int mn = 1000 /*MAX_INT*/; /* Maximal numer of actual arguments that can be
2042  used. */
2043 
2044  if(pll != gen_length(pc)) {
2045  /* This may happen with a void declaration */
2046  if(pll==0 && !ENDP(pl)) {
2047  // void function
2048  int na = (int) gen_length(pc);
2049  semantics_user_warning("%d actual arguments for void function \"%s\".\n", na,
2050  entity_user_name(f));
2051  pips_user_error("Call site incompatible with void function.");
2052  }
2053  else if(pll < gen_length(pc)) {
2054  /* This may happen with a varargs: the number of actual
2055  arguments is greater than or equal to the number of formal
2056  parameters */
2057  if(pll==0) {
2058  /* FI: this case could be processed... */
2059  semantics_user_warning("Different numbers of actual and formal parameters"
2060  "(%d and %d) for function \"%s\"\n",
2062  mn = -1;
2063  }
2064  else {
2065  parameter lp = PARAMETER(CAR(gen_last(pl)));
2066  type lpt = ultimate_type(parameter_type(lp));
2067  if(type_varargs_p(lpt)) {
2068  /* The first actual arguments can be used */
2069  mn = pll;
2070  }
2071  else {
2072  pips_user_error("Different numbers of actual and formal parameters"
2073  "(%d and %d) for function \"%s\"\n",
2075  }
2076  }
2077  }
2078  else {
2079  pips_user_error("Incompatible numbers of actual and formal parameters"
2080  "(%d and %d) for function \"%s\"\n",
2081  gen_length(pc), pll, entity_user_name(f));
2082  }
2083  }
2084  else
2085  mn = pll;
2086 
2087  if(mn>=0) {
2088  /* Evaluate actual arguments from left to right linking it to a
2089  functional parameter when possible */
2090  FOREACH(EXPRESSION, e, pc) {
2091  type fpt = compute_basic_concrete_type(parameter_type(PARAMETER(CAR(cpl)))); // formal parameter type
2092  type apt = compute_basic_concrete_type(expression_to_type(e)); // actual parameter type
2093  entity fpv = find_ith_parameter(f, n); // formal parameter variable (and value)
2094  /* Because we are using the caller's framework, we cannot use the
2095  new/old value naming in the callee's framework
2096 
2097  entity fpvv = entity_to_new_value(fpv);
2098 
2099  Let's cheat: we know fpvv would be fpv. Furthermore, the formal
2100  parameter cannot be updated in C because of the value passing
2101  mode.
2102  */
2103  basic ab = variable_basic(type_variable(apt));
2104  basic fb = variable_basic(type_variable(fpt));
2105  basic b = basic_of_expression(e);
2107 
2108  if(entity_undefined_p(fpv)) {
2109  /* FI: we could accept a number of actual parameters greater
2110  than the number of formal parameters and move on by ignoring
2111  expression e?!? Side effects in e should be taken into
2112  account anyway... */
2113  pips_user_error("Cannot find formal parameter %d for function \"%s\"."
2114  " Mismatch between function declaration and call site."
2115  " Check the source code with flint, gcc or gfortran.\n",
2116  n, entity_user_name(f));
2117  }
2118 
2119  if(analyzable_scalar_entity_p(fpv)) {
2120  if(type_equal_p(fpt, apt)) {
2121  ctf =
2122  // FI: I'm at a loss with this fourth flag argument
2123  //safe_any_expression_to_transformer(fpv, e, cpre, true);
2124  safe_any_expression_to_transformer(fpv, e, cpre, false);
2125  }
2126  else if(basic_int_p(ab) && basic_int_p(fb)) {
2127  int as = basic_int(ab);
2128  int fs = basic_int(fb);
2129 
2130  if(as-fs==10 || fs-as==10)
2131  semantics_user_warning("Signed/unsigned integer type conversion.\n");
2132  else
2133  semantics_user_warning("Integer type conversion: actual %d and formal %d\n", as, fs);
2134  ctf = safe_any_expression_to_transformer(fpv, e, cpre, false);
2135  }
2136  else if((basic_int_p(ab) && derived_type_p(fpt))
2137  ||(basic_int_p(fb) && derived_type_p(apt)) ) {
2138  /* FI: Let's assume it is an enum derived type... Too late
2139  for a better job... */
2140 
2141  semantics_user_warning("Integer/enum or enum/integer type conversion"
2142  " for argument \"%s\" (rank %d) of function \"%s\" "
2143  "called from function \"%s\".\n",
2146 
2147  ctf = safe_any_expression_to_transformer(fpv, e, cpre, false);
2148  }
2149  else {
2151  semantics_user_warning("Type incompatibility between call site and declaration"
2152  " for argument \"%s\" (rank %d) of function \"%s\" "
2153  "called from function \"%s\": %s/%s\n",
2156  basic_to_string(fb), basic_to_string(ab));
2157 
2158  ctf = effects_to_transformer(el);
2159  }
2160  }
2161  else if(struct_type_p(apt)
2162  && struct_type_p(fpt)
2163  && get_bool_property("SEMANTICS_ANALYZE_CONSTANT_PATH")) {
2164  ctf = struct_variable_equality_to_transformer(fpv, fpt, e, cpre, NIL);
2165  // FI: what should we do when cft is undefined ?
2166  }
2167  else {
2168  /* The associated transformer may nevertheless carry useful/necessary
2169  information */
2170  //list el = expression_to_proper_effects(e);
2172 
2173  ctf = effects_to_transformer(el);
2174  }
2175 
2177 
2178  tf = transformer_combine(tf, ctf);
2179  npre = transformer_apply(ctf, cpre);
2180  npre = transformer_normalize(npre, 2);
2181  free_transformer(cpre);
2182  cpre = npre;
2183  POP(cpl);
2184  n++;
2185  free_type(apt);
2186  free_basic(b);
2187  /* Can we still use the next actual parameter? Maybe not because
2188  of a vararg. */
2189  if(n>mn) break;
2190  }
2191  }
2192 
2193  return tf;
2194 }
void free_type(type p)
Definition: ri.c:2658
void free_basic(basic p)
Definition: ri.c:107
transformer copy_transformer(transformer p)
TRANSFORMER.
Definition: ri.c:2613
transformer transformer_identity()
Allocate an identity transformer.
Definition: basic.c:110
list expression_to_proper_constant_path_effects(expression)
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
#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
list gen_last(list l)
Return the last element of a list.
Definition: list.c:578
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
string basic_to_string(basic)
Definition: type.c:87
static hash_table pl
properties are stored in this hash table (string -> property) for fast accesses.
Definition: properties.c:783
basic basic_of_expression(expression)
basic basic_of_expression(expression exp): Makes a basic of the same basic as the expression "exp".
Definition: type.c:1383
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_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 derived_type_p(type)
Returns true if t is of type struct, union or enum.
Definition: type.c:3104
bool struct_type_p(type)
Returns true if t is of type derived and if the derived type is a struct.
Definition: type.c:3121
type compute_basic_concrete_type(type)
computes a new type which is the basic concrete type of the input type (this new type is not stored i...
Definition: type.c:3556
entity find_ith_parameter(entity, int)
Definition: util.c:93
#define parameter_type(x)
Definition: ri.h:1819
#define basic_int_p(x)
Definition: ri.h:614
#define basic_int(x)
Definition: ri.h:616
#define type_functional(x)
Definition: ri.h:2952
#define type_variable(x)
Definition: ri.h:2949
#define entity_undefined_p(x)
Definition: ri.h:2762
#define functional_parameters(x)
Definition: ri.h:1442
#define PARAMETER(x)
PARAMETER.
Definition: ri.h:1788
#define type_varargs_p(x)
Definition: ri.h:2953
#define variable_basic(x)
Definition: ri.h:3120
transformer struct_variable_equality_to_transformer(entity v, type t, expression rhs, transformer pre, list ef)
unsigned int number_of_usable_functional_parameters(list pl)
Number of formal parameters in pl before a vararg is reached.
transformer safe_any_expression_to_transformer(entity v, expression expr, transformer pre, bool is_internal)
Always return a usable transformer.
Definition: expression.c:5156
transformer transformer_normalize(transformer t, int level)
Eliminate (some) rational or integer redundancy.
Definition: transformer.c:932
bool analyzable_scalar_entity_p(entity)
The entity type is one of the analyzed types.
Definition: value.c:471

References analyzable_scalar_entity_p(), basic_int, basic_int_p, basic_of_expression(), basic_to_string(), CAR, compute_basic_concrete_type(), copy_transformer(), derived_type_p(), effects_to_transformer(), ENDP, entity_basic_concrete_type(), entity_undefined_p, entity_user_name(), EXPRESSION, expression_to_proper_constant_path_effects(), expression_to_type(), f(), find_ith_parameter(), FOREACH, free_basic(), free_transformer(), free_type(), functional_parameters, gen_last(), gen_length(), get_bool_property(), get_current_module_entity(), int, NIL, number_of_usable_functional_parameters(), PARAMETER, parameter_type, pips_user_error, pl, POP, safe_any_expression_to_transformer(), semantics_user_warning, struct_type_p(), struct_variable_equality_to_transformer(), transformer_apply(), transformer_combine(), transformer_identity(), transformer_normalize(), transformer_undefined, transformer_undefined_p, type_equal_p(), type_functional, type_varargs_p, type_variable, ultimate_type(), and variable_basic.

Referenced by c_user_call_to_transformer(), and new_add_formal_to_actual_bindings().

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

◆ apply_abstract_effect_to_transformer()

static transformer apply_abstract_effect_to_transformer ( transformer  tf,
effect  e,
bool  apply_p 
)
static

Apply or add an abstract effect e on a transformer tf we must verify that the effect e is a write effect and the effect of e is on abstract variable

Parameters
tftransformer
eabstract write effects
apply_pif we apply or add an effect, true if we apply
Returns
transformer with the effect

All analyzed variables conflicting with v must be considered written.

This should depend on the abstract location, its type when anywhere effects are typed, and its scope when abstract locations can be restricted to a module or a compilation unit. See the lattice defined by Amira Mensi.

FI: no, you lose all constraints containing new values, but constraints on old values are preserved, not matter how useless they are.

FC

sc_projection_along_variable_ofl_ctrl_timeout_ctrl

Definition at line 150 of file ri_to_transformers.c.

151 {
152  ifdebug(8) {
153  pips_debug(8, "Begin\n");
154  (void) print_transformer(tf);
155  }
157 
158  /* All analyzed variables conflicting with v must be considered
159  * written.
160  *
161  * This should depend on the abstract location, its type when
162  * anywhere effects are typed, and its scope when abstract
163  * locations can be restricted to a module or a compilation
164  * unit. See the lattice defined by Amira Mensi.
165  */
167 
168  FOREACH(ENTITY, wv, wvl)
169  {
170  ifdebug(8) {
171  (void) print_entity_variable(wv);
172  }
173  //NL : only modified variable with conflict with the effect is treat
175  if (apply_p) {
176  //NL : if we apply effect, we need to check where the effect take place
178  // NL : need to make a function to make transformer_cylinder_base_projection(tf, wv)
179  //TODO : transformer_cylinder_base_projection(tf, wv);
181  }
182  else {
183  // NL : v and not wv, don't know why (come from effect with pointer values)
184  // for testcase Effects/Effects_With_Pointer_Values.sub/dereferencing04(_2)
185  // NL : transformer_add_variable_update need to be complete
186  // not sure if we have to use transformer_add_variable_update or transformer_add_value_update
187 
188  // FI: v does not make sense, wv is a variable, v an
189  // abstract location by definition of the function name ?
191  //transformer_add_value_update(tf, v);
192  }
193  }
194  //NL : else we add effect, we just need to add the variable
195  else {
196  // NL : transformer_add_variable_update need to be complete
197  // not sure if we have to use transformer_add_variable_update or transformer_add_value_update
199  //transformer_add_value_update(tf, wv);
200  }
201  }
202  }
203 
204  //TODO : delete this IF when transformer_cylinder_base_projection done
205  // NL : if the effect is to write *ANYWHERE*, we lose all the constraint
206  /* FI: no, you lose all constraints containing new values, but
207  * constraints on old values are preserved, not matter how useless
208  * they are.
209  */
210  if (apply_p && entity_all_module_locations_p(v))
211  {
212 #if 0
214  sc_egalites(sc) = contraintes_free(sc_egalites(sc));
215  sc_nbre_egalites(sc) = 0;
216  sc_inegalites(sc) = contraintes_free(sc_inegalites(sc));
217  sc_nbre_inegalites(sc) = 0;
218 #elseif 0
219  // FI: quick and dirty fix, overflows are not handled
221  list al = transformer_arguments(tf);
222  FOREACH(ENTITY, a, al) {
223  sc = sc_elim_var(sc, (Variable) a);
224  }
225 #else
227  list volatile al = transformer_arguments(tf);
228  // FI: FOREACH removed because of warnings in new version of gcc
229  while(!ENDP(al)) {
230  entity volatile e = ENTITY(CAR(al)); // To add the volatile keyword
232  {
233  /* FC */
234  pips_user_warning("overflow error in projection of %s, "
235  "variable eliminated\n",
236  entity_name(e));
237  r = sc_elim_var(r, (Variable) e);
238  }
239  TRY
240  {
241  /* sc_projection_along_variable_ofl_ctrl_timeout_ctrl */
242  sc_projection_along_variable_ofl_ctrl
243  (&r,(Variable) e, NO_OFL_CTRL);
245  }
246  POP(al);
247  }
248 #endif
249  }
250 
251  ifdebug(8) {
252  (void) print_transformer(tf);
253  pips_debug(8, "Ends\n");
254  }
255  return tf;
256 }
bool entity_all_module_locations_p(entity e)
test if an entity is the set of locations defined in a module
#define CATCH(what)
@ overflow_error
#define UNCATCH(what)
#define TRY
transformer transformer_add_variable_update(transformer t, entity v)
Add an update of variable v into t.
Definition: basic.c:289
Pcontrainte contraintes_free(Pcontrainte pc)
Pcontrainte contraintes_free(Pcontrainte pc): desallocation de toutes les contraintes de la liste pc.
Definition: alloc.c:226
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
bool entities_may_conflict_p(entity e1, entity e2)
Check if two entities may conflict.
Definition: conflicts.c:984
#define pips_user_warning
Definition: misc-local.h:146
void print_entity_variable(entity e)
print_entity_variable(e)
Definition: entity.c:56
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define entity_name(x)
Definition: ri.h:2790
#define transformer_relation(x)
Definition: ri.h:2873
#define predicate_system(x)
Definition: ri.h:2069
Psysteme sc_elim_var(Psysteme sc, Variable v)
package sur les systemes de contraintes sc
Definition: sc_unaires.c:49
list modified_variables_with_values(void)
Return the list of all analyzed variables which are modified in the current module.
Definition: value.c:1094
#define NO_OFL_CTRL
void * Variable
arithmetique is a requirement for vecteur, but I do not want to inforce it in all pips files....
Definition: vecteur-local.h:60

References CAR, CATCH, contraintes_free(), effect_any_reference, ENDP, entities_may_conflict_p(), ENTITY, entity_all_module_locations_p(), entity_has_values_p(), entity_name, FOREACH, ifdebug, modified_variables_with_values(), NO_OFL_CTRL, overflow_error, pips_debug, pips_user_warning, POP, predicate_system, print_entity_variable(), print_transformer, reference_variable, sc_elim_var(), transformer_add_variable_update(), transformer_arguments, transformer_relation, TRY, and UNCATCH.

Referenced by generic_apply_effect_to_transformer().

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

◆ apply_abstract_effects_to_transformer()

static transformer apply_abstract_effects_to_transformer ( transformer  tf,
list  el 
)
static

Definition at line 469 of file ri_to_transformers.c.

470 {
471  return generic_apply_effects_to_transformer(tf, el, true, expression_undefined, true, true);
472 }
static transformer generic_apply_effects_to_transformer(transformer tf, list el, bool apply_p, expression rhs, bool additional_p, bool abstract_p)
These two functions are not currently used static transformer apply_effect_to_transformer(transformer...

References expression_undefined, and generic_apply_effects_to_transformer().

Referenced by statement_to_transformer().

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

◆ apply_additional_effects_to_transformer()

static transformer apply_additional_effects_to_transformer ( transformer  tf,
list  el,
bool  apply_p,
expression  rhs 
)
static

Definition at line 464 of file ri_to_transformers.c.

465 {
466  return generic_apply_effects_to_transformer(tf, el, apply_p, rhs, true, false);
467 }

References generic_apply_effects_to_transformer().

Referenced by any_assign_to_transformer().

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

◆ apply_array_effect_to_transformer()

transformer apply_array_effect_to_transformer ( transformer  tf,
effect e   __attribute__(unused),
bool apply_p   __attribute__(unused) 
)

Effect e is assumed to be a memory write effect on an array element location.

This must be checked by the caller.

A precondition should be passed to check conflicts more precisely.

Definition at line 263 of file ri_to_transformers.c.

264 {
265  // similar to apply_abstract_effect_to_transformer(), but conflicts
266  // must be tested at the reference level, not at the entity level
268  // The location may not appear yet in tf...
269  // list ll = transformer_to_analyzed_array_locations(tf);
272 
273  FOREACH(ENTITY, l, ll) {
274  value lv = entity_initial(l);
275  reference lr = value_reference(lv);
276  if(references_may_conflict_p(er, lr)) {
278  }
279  }
280 
281  return tf;
282 }
list module_to_analyzed_array_locations(entity)
m is supposed to be a module entity
Definition: locations.c:393
bool references_may_conflict_p(reference r1, reference r2)
Check if two references may conflict.
Definition: conflicts.c:426
#define value_reference(x)
Definition: ri.h:3085
#define entity_initial(x)
Definition: ri.h:2796

References effect_any_reference, ENTITY, entity_initial, FOREACH, get_current_module_entity(), module_to_analyzed_array_locations(), references_may_conflict_p(), transformer_add_variable_update(), and value_reference.

Referenced by generic_apply_effect_to_transformer().

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

◆ apply_concrete_effect_to_transformer()

static transformer apply_concrete_effect_to_transformer ( transformer  tf,
effect  e,
expression __attribute__((unused))  rhs 
)
static

semantical analysis

phasis 1: compute transformers from statements and statements effects

For (simple) interprocedural analysis, this phasis should be performed bottom-up on the call tree.

Francois Irigoin, April 1990 include <stdlib.h> static stack current_statement_semantic_context = stack_undefined; void init_current_statement_semantic_context() { pips_assert("current_statement_semantic_context is undefined", stack_undefined_p(current_statement_semantic_context)); current_statement_semantic_context = stack_make(statement_domain, 0, 0); } static void push_current_statement_semantic_context(statement st) { stack_push((void *) st, current_statement_semantic_context); } statement get_current_statement_semantic_context() { statement st = (statement) stack_head(current_statement_semantic_context); return st; } static statement pop_current_statement_semantic_context(void) { statement st = (statement) stack_pop(current_statement_semantic_context); return st; } void free_current_statement_semantic_context() { stack_free(&current_statement_semantic_context); current_statement_semantic_context = stack_undefined; } bool current_statement_semantic_context_defined_p() { return !stack_undefined_p(current_statement_semantic_context); }

Apply or add an "concrete" effect e on a transformer tf we must verify that the effect e is a write effect and the effect of e is on abstract variable

Parameters
tftransformer
ewrite effect (assumed), on a concrete location (assumed)
rhssome expression. more or less linked to the effect, useful if error r warning messages are emitted
Returns
transformer with the effect

Definition at line 129 of file ri_to_transformers.c.

130 {
133  if(!entity_undefined_p(l)) {
134  // FI: I am not sure the necessry projection is performed
135  // you would need t1 = effect_to_transformer(e), tf = t1(tf)
137  }
138  return tf;
139 }
entity constant_memory_access_path_to_location_entity(reference)
A constant memory access path may not be considered.
Definition: locations.c:329

References constant_memory_access_path_to_location_entity(), effect_any_reference, entity_undefined_p, and transformer_add_variable_update().

Referenced by generic_apply_effect_to_transformer().

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

◆ apply_effects_to_transformer()

static transformer apply_effects_to_transformer ( transformer  tf,
list  el,
bool  apply_p,
expression  rhs 
)
static

Definition at line 459 of file ri_to_transformers.c.

460 {
461  return generic_apply_effects_to_transformer(tf, el, apply_p, rhs, false, false);
462 }

References generic_apply_effects_to_transformer().

Referenced by effects_to_transformer().

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

◆ array_elements_substitution_in_transformer()

transformer array_elements_substitution_in_transformer ( transformer  tf,
entity  fpv,
type  fpt,
expression  e,
transformer cpre   __attribute__(unused),
list el   __attribute__(unused),
bool  backward_p 
)

e should be a reference to an array

What are the dimensions of the formal parameter ?

Definition at line 1701 of file ri_to_transformers.c.

1702 {
1703  /* e should be a reference to an array */
1704  pips_assert("e is a reference", expression_reference_p(e));
1705  reference ar = expression_reference(e); // actual reference
1706 
1707  /* What are the dimensions of the formal parameter ? */
1708  pips_assert("fpt is an array type", type_variable_p(fpt));
1709  variable v = type_variable(fpt);
1710  list dl = variable_dimensions(v);
1711  reference fr = make_reference(fpv, NIL);
1712 
1713  perform_array_element_substitutions_in_transformer(tf, ar, fr, dl, cpre, backward_p);
1714 
1715  free_reference(fr);
1716 
1717  return tf;
1718 }
void free_reference(reference p)
Definition: ri.c:2050
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
#define variable_dimensions(x)
Definition: ri.h:3122
#define type_variable_p(x)
Definition: ri.h:2947
static void perform_array_element_substitutions_in_transformer(transformer tf, reference ar, reference fr, list dl, transformer prec __attribute__((unused)), bool backward_p)
Recursive function to substitute formal and actual array elements referenced or partially referenced ...

References expression_reference(), expression_reference_p(), free_reference(), make_reference(), NIL, perform_array_element_substitutions_in_transformer(), pips_assert, type_variable, type_variable_p, and variable_dimensions.

+ Here is the call graph for this function:

◆ assign_rhs_to_cp_to_transformer()

static transformer assign_rhs_to_cp_to_transformer ( reference  cp,
expression  rhs,
transformer  pre,
list  ef 
)
static
Parameters
cpconstant path to be assign (the caller need to verify that cp is really a constant path)
rhsexpression to assign
preprecondition
efeffects of assign
Returns
transformer_undefined or transformer with the assignment

Definition at line 2852 of file ri_to_transformers.c.

2857 {
2860 
2861  if(!entity_undefined_p(ecp))
2862  tf = any_scalar_assign_to_transformer(ecp, rhs, ef, pre);
2863 
2864  return tf;
2865 }
transformer any_scalar_assign_to_transformer(entity v, expression rhs, list ef, transformer pre)
precondition

References any_scalar_assign_to_transformer(), constant_memory_access_path_to_location_entity(), cp, entity_undefined_p, and transformer_undefined.

Referenced by assign_rhs_to_reflhs_to_transformer(), and basic_update_reflhs_with_rhs_to_transformer().

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

◆ assign_rhs_to_reflhs_to_transformer()

static transformer assign_rhs_to_reflhs_to_transformer ( reference  rlhs,
expression  rhs,
transformer  pre,
list  ef 
)
static
Parameters
rlhsreference to be assigned
rhsexpression assigned
preprecondition (range of a precondition?)
efeffects of assign
Returns
transformer_undefined or transformer with the assign

check scalar side effects in the subscript expressions and in the rhs (specific to C)

FI: not clear why this happens in Fortran and not in C

Definition at line 3123 of file ri_to_transformers.c.

3128 {
3130 
3131  if(ENDP(reference_indices(rlhs))) {
3132  entity v = reference_variable(rlhs);
3134  if(analyzed_type_p(t))
3135  tf = any_scalar_assign_to_transformer(v, rhs, ef, pre);
3136  else if(constant_path_analyzed_p() && struct_type_p(t)) {
3137  tf = struct_variable_assignment_to_transformer(v, t, rhs, pre, ef);
3138  }
3139  }
3140  else if (constant_path_analyzed_p()) {
3141  if (analyzed_reference_p(rlhs)) {
3142  tf = assign_rhs_to_cp_to_transformer(rlhs, rhs, pre, ef);
3143  }
3144  else {
3147  tf = struct_reference_assignment_to_transformer(rlhs, t, rhs, pre, ef);
3148  else {
3149  // FI: no idea which other cases should be handled
3150  ;
3151  }
3152  }
3153  }
3154 
3155  if(transformer_undefined_p(tf)) {
3156  /* check scalar side effects in the subscript expressions and
3157  in the rhs (specific to C) */
3158  // FI: I assume that the value is never useful because of the
3159  // above condition
3160  transformer st // subscript transformer
3162  /* FI: not clear why this happens in Fortran and not in C */
3163  if(!transformer_undefined_p(st)) {
3164  transformer post = transformer_apply(st, pre);
3165  transformer npre = transformer_range(post);
3166  transformer rt = safe_expression_to_transformer(rhs, npre); // rhs
3167  tf = transformer_combine(st, rt); // st is absorbed into tf
3168  free_transformer(rt);
3169  free_transformer(npre);
3170  free_transformer(post);
3171  }
3172  }
3173 
3174  return tf;
3175 }
type points_to_reference_to_concrete_type(reference)
Definition: type.c:685
bool store_independent_points_to_reference_p(reference)
Functions for points-to references, the kind of references used in points-to cells.
Definition: points_to.c:1247
#define entity_undefined
Definition: ri.h:2761
#define reference_indices(x)
Definition: ri.h:2328
transformer struct_variable_assignment_to_transformer(entity v, type t, expression rhs, transformer pre, list ef)
transformer struct_reference_assignment_to_transformer(reference r, type t, expression rhs, transformer pre, list ef)
static transformer assign_rhs_to_cp_to_transformer(reference cp, expression rhs, transformer pre, list ef)
transformer generic_reference_to_transformer(entity v, reference r, transformer pre, bool is_internal)
TYPE INDEPENDENT OPERATIONS.
Definition: expression.c:126
transformer transformer_range(transformer tf)
Return the range of relation tf in a newly allocated transformer.
Definition: transformer.c:714
bool analyzed_type_p(type)
The type t is one of the analyzed types.
Definition: value.c:367

References analyzed_reference_p(), analyzed_type_p(), any_scalar_assign_to_transformer(), assign_rhs_to_cp_to_transformer(), constant_path_analyzed_p(), ENDP, entity_basic_concrete_type(), entity_undefined, free_transformer(), generic_reference_to_transformer(), points_to_reference_to_concrete_type(), reference_indices, reference_variable, safe_expression_to_transformer(), store_independent_points_to_reference_p(), struct_reference_assignment_to_transformer(), struct_type_p(), struct_variable_assignment_to_transformer(), transformer_apply(), transformer_combine(), transformer_range(), transformer_undefined, and transformer_undefined_p.

Referenced by any_assign_to_transformer().

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

◆ assigned_expression_to_transformer()

transformer assigned_expression_to_transformer ( entity  v,
expression  expr,
transformer  pre 
)

transformer assigned_expression_to_transformer(entity e, expression expr, list ef): returns a transformer abstracting the effect of assignment "e = expr" when possible, transformer_undefined otherwise.

Note: it might be better to distinguish further between e and expr and to return a transformer stating that e is modified when e is accepted for semantics analysis.

if the assigned variable is also assigned by the expression as in i = (i = 2) + 1, transformer_value_substitute() cannot be used right away. The previous store must be projected out.

v must be assigned

subcase of previous aternative

vect_rm(ve);

Parameters
exprxpr
prere

Definition at line 2595 of file ri_to_transformers.c.

2598 {
2600 
2601  pips_debug(8, "begin\n");
2602 
2603  if(entity_has_values_p(v)) {
2604  entity v_new = entity_to_new_value(v);
2606  //list tf_args = CONS(ENTITY, v, NIL);
2607 
2608  tf = any_expression_to_transformer(tmp, expr, pre, true);
2609  // The assignment may be part of a more complex expression
2610  // This should be guarded by "is_internal==FALSE" if is_internal were an argument
2611  //reset_temporary_value_counter();
2612  if(!transformer_undefined_p(tf)) {
2613  /* if the assigned variable is also assigned by the expression
2614  as in i = (i = 2) + 1, transformer_value_substitute() cannot be
2615  used right away. The previous store must be projected out. */
2617  /* v must be assigned */
2618  transformer teq = simple_equality_to_transformer(v, tmp, true);
2619  tf = transformer_combine(tf, teq);
2620  free_transformer(teq);
2621 
2622  }
2623  else { /* subcase of previous aternative */
2624  entity v_old = entity_to_old_value(v);
2625  tf = transformer_value_substitute(tf, v_new, v_old);
2626  tf = transformer_value_substitute(tf, tmp, v_new);
2627  // v cannot be a temporary variable
2628  //transformer_arguments(tf) =
2629  //arguments_add_entity(transformer_arguments(tf), v);
2630  tf = transformer_add_value_update(tf, v);
2631  }
2633  }
2634  }
2635  else {
2636  /* vect_rm(ve); */
2637  tf = transformer_undefined;
2638  }
2639 
2640  pips_debug(8, "end with tf=%p\n", tf);
2641 
2642  return tf;
2643 }
transformer transformer_add_value_update(transformer t, entity v)
Add an update of variable v to t (a value cannot be updated)
Definition: basic.c:321

References any_expression_to_transformer(), entity_has_values_p(), entity_is_argument_p(), entity_to_new_value(), entity_to_old_value(), entity_type, free_transformer(), make_local_temporary_value_entity(), pips_debug, simple_equality_to_transformer(), transformer_add_value_update(), transformer_arguments, transformer_combine(), transformer_temporary_value_projection(), transformer_undefined, transformer_undefined_p, and transformer_value_substitute().

Referenced by assign_operation_to_transformer(), integer_assign_to_transformer(), integer_assign_to_transformer_list(), loop_to_initialization_transformer(), safe_assigned_expression_to_transformer(), and safe_assigned_expression_to_transformer_list().

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

◆ basic_update_reflhs_with_rhs_to_transformer()

static transformer basic_update_reflhs_with_rhs_to_transformer ( entity  op,
reference  rlhs,
expression  rhs,
transformer  pre,
list  ef 
)
static
Parameters
opupdate operator
rlhsreference to be update
rhsexpression to assign
preprecondition
efeffects of assign
Returns
transformer_undefined or transformer with the update

Definition at line 3479 of file ri_to_transformers.c.

3485 {
3487 
3491 
3493  ve = int_to_expression(1);
3494  else
3495  ve = int_to_expression(-1);
3496  n_rhs = MakeBinaryCall(plus, ve, copy_expression(rhs));
3497 
3498 
3499  if(ENDP(reference_indices(rlhs))) {
3500  entity v = reference_variable(rlhs);
3501 
3502  tf = any_scalar_assign_to_transformer(v, n_rhs, ef, pre);
3503  }
3504  else if (constant_path_analyzed_p()) { // see assign_rhs_to_reflhs_to_transformer
3505  if (store_independent_reference_p(rlhs)) {
3506  // FI: why not use any_scalar_assign_to_transformer once lhs is
3507  // transformer into an entity?
3508  tf = assign_rhs_to_cp_to_transformer(rlhs, n_rhs, pre, ef);
3509  }
3510  else {
3511  // TODO : reference_to_constant_path(ref)
3512  // function that convert any reference in a constant path
3513  // expression_to_points_to_sources() isn't good, doesn't work for some array for the moment
3514  // maybe reference_to_sinks() it's ok, not tested
3515  // we are in this case for the array I think
3516  semantics_user_warning("Want to analyse constant path, but don't have a constant path : %s\n", reference_to_string(rlhs));
3517  // tf = assign_rhs_to_cp_to_transformer( cp , rhs, pre, ef);
3518  }
3519  }
3520 
3521  free_expression(n_rhs);
3522  return tf;
3523 }
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
void free_expression(expression p)
Definition: ri.c:853
#define ENTITY_POST_INCREMENT_P(e)
#define ENTITY_PRE_INCREMENT_P(e)
#define PLUS_C_OPERATOR_NAME
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188
bool store_independent_reference_p(reference r)
Does this reference define the same set of memory locations regardless of the current (environment an...
Definition: expression.c:3108

References any_scalar_assign_to_transformer(), assign_rhs_to_cp_to_transformer(), constant_path_analyzed_p(), copy_expression(), ENDP, entity_intrinsic(), ENTITY_POST_INCREMENT_P, ENTITY_PRE_INCREMENT_P, expression_undefined, free_expression(), int_to_expression(), MakeBinaryCall(), PLUS_C_OPERATOR_NAME, reference_indices, reference_to_string(), reference_variable, semantics_user_warning, store_independent_reference_p(), and transformer_undefined.

Referenced by any_basic_update_to_transformer().

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

◆ block_to_transformer()

static transformer block_to_transformer ( list  b,
transformer  pre 
)
static

Recursive Descent in Data Structure Statement.

SHARING : returns the transformer stored in the database. Make a copy before using it. The copy is not made here because the result is not always used after a call to this function, and it would create non reachable structures. Another solution would be to store a copy and free the unused result in the calling function but transformer_free does not really free the transformer. Not very clean. BC, oct. 94 Compute the transformer of a block "b" under precondition "pre".

Note that information about variables declared within the block is not projected here, but in statement_to_transformer().

Precondition pre may be undefined to compute transformers purely upwards or be defined if the transformers are refined (apply REFINE_TRANSFORMERS) or if the transformers are computed in context.

FI: it is not clear if postconditions should be propagated or if the range of the current transformer is exactly what is needed to compute the transformer of the next statement.

When precondition pre is undefined, this piece of code is supposed to behave as if preconditions were never calculated nor used. The complexiy problem encountered with Semantics/mpeg2enc even with the option SEMANTICS_COMPUTE_TRANSFORMERS_IN_CONTEXT false seems to indicate that we end up with usable preconditions even when they are not needed.

FI: more investigation is needed to control the execution time. The spontaneous computation of preconditions would lead to a time increase at all levels, for instance when non-affine operators are approximated. The behavior of block_to_transformer() seems OK with Semantics-New/block01. It should be checked again with Semantics-New mpeg2enc.

post = transformer_safe_normalize(post, 4);

post = transformer_safe_normalize(post, 4);

btf = transformer_normalize(btf, 4);

Definition at line 734 of file ri_to_transformers.c.

735 {
736  statement s;
741  list l = b;
742 
743  pips_debug(8,"begin\n");
744 
745  if(ENDP(l))
746  btf = transformer_identity();
747  else {
748  s = STATEMENT(CAR(l));
749  stf = statement_to_transformer(s, pre);
750  post = transformer_safe_apply(stf, pre);
751 /* post = transformer_safe_normalize(post, 4); */
752  post = transformer_safe_normalize(post, 2);
753  btf = transformer_dup(stf);
754  for (POP(l) ; !ENDP(l); POP(l)) {
755  s = STATEMENT(CAR(l));
756  if(!transformer_undefined_p(next_pre))
757  free_transformer(next_pre);
758 
759  // In case "ocean", this is a performance bug due to r18644
760  // next_pre = transformer_range(post);
761  // free_transformer(post);
762  next_pre = post;
763 
764  stf = statement_to_transformer(s, next_pre);
765  post = transformer_safe_apply(stf, next_pre);
766 /* post = transformer_safe_normalize(post, 4); */
767  post = transformer_safe_normalize(post, 2);
768  btf = transformer_combine(btf, stf);
769 /* btf = transformer_normalize(btf, 4); */
770  btf = transformer_normalize(btf, 2);
771  ifdebug(1)
772  pips_assert("btf is a consistent transformer", transformer_consistency_p(btf));
773  pips_assert("post is a consistent transformer if pre is defined",
775  }
776  free_transformer(post);
777  }
778 
779  // FI: I add a stronger normalization at the end of the block
780  //
781  // The lighter normalization (level 2) in the loop was introduced to deal with very long
782  // basic blocks generated by Scilab (I believe). This light
783  // normalization does not detect equations split into two
784  // inequalities, not identical constraints... What does it deal with?
785  //
786  // The stronger normalization (level 4) is added for putnonintrablk() from
787  // mpeg2, although it's probably too late to recover from the very
788  // large coefficients introduced earlier
789  //
790  // FI: does not seem to do much good because the normalization may
791  // increase the complexity of the constraints
792  // btf = transformer_normalize(btf, 4);
793 
794  pips_debug(8, "end\n");
795  return btf;
796 }
transformer transformer_dup(transformer t_in)
transformer package - basic routines
Definition: basic.c:49
bool transformer_consistency_p(transformer t)
FI: I do not know if this procedure should always return or fail when an inconsistency is found.
Definition: basic.c:612
char end
Definition: gtk_status.c:82
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
transformer statement_to_transformer(statement s, transformer spre)
stmt precondition
bool stf(const string)
standardize_structure.c
transformer transformer_safe_apply(transformer tf, transformer pre)
Definition: transformer.c:1627
transformer transformer_safe_normalize(transformer t, int level)
Definition: transformer.c:1111

References CAR, ENDP, free_transformer(), ifdebug, pips_assert, pips_debug, POP, STATEMENT, statement_to_transformer(), stf(), transformer_combine(), transformer_consistency_p(), transformer_dup(), transformer_identity(), transformer_normalize(), transformer_safe_apply(), transformer_safe_normalize(), transformer_undefined, and transformer_undefined_p.

Referenced by instruction_to_transformer().

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

◆ c_return_to_transformer()

transformer c_return_to_transformer ( entity e   __attribute__(__unused__),
list  pc,
list  ef,
transformer  pre 
)

FI: This transformer carry the information about the value returned, but not the fact that the next statement is not reached.

FI: Are we sure the return value entity has values? No...

if(entity_has_values_p(rv)) {

Definition at line 2532 of file ri_to_transformers.c.

2534 {
2537  const char* mn = entity_local_name(m);
2538  entity rv = FindEntity(mn, mn);
2539 
2540  if(ENDP(pc))
2541  tf = transformer_identity();
2542  else {
2544  // FI: issue with entity_basic_concrete_type: does not process the
2545  // returned type of a functional
2547 
2548  pips_assert("A module has a functional type", type_functional_p(umt));
2549 
2550  if(!type_void_p(rt)) {
2551  //type urt = ultimate_type(rt);
2552  //basic b = variable_basic(type_variable(urt));
2553 
2554  /* FI: Are we sure the return value entity has values? No... */
2555  /* if(entity_has_values_p(rv)) {*/
2556  expression expr = EXPRESSION(CAR(pc));
2557  if(analyzable_scalar_entity_p(rv)) {
2558  //entity rvv = entity_to_new_value(rv);
2559 
2560  tf = any_expression_to_transformer(rv, expr, pre, false);
2561  if(transformer_undefined_p(tf))
2562  tf = effects_to_transformer(ef);
2563  else
2565  tf = transformer_add_value_update(tf, rv);
2566  }
2567  else if(struct_type_p(rt)
2568  && get_bool_property("SEMANTICS_ANALYZE_CONSTANT_PATH")) {
2569  tf = struct_variable_assignment_to_transformer(rv, rt, expr, pre, ef);
2570  tf = generic_transformer_intra_to_inter(tf, ef, false);
2571  }
2572  }
2573  else {
2574  pips_user_error("value returned from a void function\n");
2575  }
2576 
2577  if(transformer_undefined_p(tf))
2578  tf = effects_to_transformer(ef);
2579  }
2580 
2581  return tf;
2582 }
entity FindEntity(const char *package, const char *name)
Retrieve an entity from its package/module name and its local name.
Definition: entity.c:1503
#define type_functional_p(x)
Definition: ri.h:2950
#define functional_result(x)
Definition: ri.h:1444
#define type_void_p(x)
Definition: ri.h:2959
transformer generic_transformer_intra_to_inter(transformer tf, list le, bool preserve_rv_p)
transformer translation from the module intraprocedural transformer to the module interprocedural tra...

References analyzable_scalar_entity_p(), any_expression_to_transformer(), CAR, compute_basic_concrete_type(), effects_to_transformer(), ENDP, entity_basic_concrete_type(), entity_local_name(), EXPRESSION, FindEntity(), functional_result, generic_transformer_intra_to_inter(), get_bool_property(), get_current_module_entity(), pips_assert, pips_user_error, struct_type_p(), struct_variable_assignment_to_transformer(), transformer_add_value_update(), transformer_identity(), transformer_temporary_value_projection(), transformer_undefined, transformer_undefined_p, type_functional, type_functional_p, and type_void_p.

Referenced by intrinsic_to_transformer(), and intrinsic_to_transformer_list().

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

◆ c_user_call_to_transformer()

transformer c_user_call_to_transformer ( entity  f,
list  pc,
transformer  pre,
list  ef 
)

Compute the call site transformer, the bindings between formal entities and actual argments

substitute stubs and formal array elements which are passed directly or indirectly by reference if requested

Combine tf with the summary transformer

Project the former parameters and the temporary values.

Check the consistency of the transformer with the constant effects

Parameters
pcc
prere
eff

Definition at line 2196 of file ri_to_transformers.c.

2200 {
2203 
2204  pips_assert("t_callee is consistent", transformer_weak_consistency_p(t_callee));
2205 
2206  /* Compute the call site transformer, the bindings between formal
2207  entities and actual argments */
2208  tf = any_user_call_site_to_transformer(f, pc, pre, ef);
2209 
2210  /* substitute stubs and formal array elements which are passed
2211  directly or indirectly by reference if requested */
2212  transformer t_bound = copy_transformer(t_callee);
2213  if(get_bool_property("SEMANTICS_ANALYZE_CONSTANT_PATH")) {
2214  call c = make_call(f, pc);
2216  // t_bound = substitute_stubs_in_transformer(t_bound, c, s, true);
2217  t_bound = new_substitute_stubs_in_transformer(t_bound, c, s, true);
2218  call_arguments(c) = NIL;
2219  free_call(c);
2220  t_bound = substitute_formal_array_elements_in_transformer(t_bound, f, pc, pre, ef);
2221  }
2222 
2223  /* Combine tf with the summary transformer */
2224  tf = transformer_combine(tf, t_bound);
2225  free_transformer(t_bound);
2226 
2227  /* Project the former parameters and the temporary values. */
2230 
2232 
2233  /* Check the consistency of the transformer with the constant effects */
2234  // list effect_to_constant_path_effects_with_no_pointer_information(effect /*eff*/);
2235  // list simple_effect_to_constant_path_effects_with_pointer_values(effect /*eff*/);
2236  // list simple_effect_to_constant_path_effects_with_points_to(effect /*eff*/);
2237  list cel = list_undefined;
2238  if(get_bool_property("CONSTANT_PATH_EFFECTS"))
2239  cel = ef;
2240  else {
2243  else {
2244  // FI: I used to call pointer_effects_to_constant_path_effects()
2245  // but it is a generic function that requires setting some
2246  // function pointers
2247  cel = NIL;
2249  FOREACH(EFFECT, e, ef) {
2251  cel = gen_nconc(cel, ncel);
2252  }
2253  }
2254  }
2256  list al = transformer_arguments(etf);
2257  tf = transformer_add_variables_update(tf, al);
2258  free_transformer(etf);
2259 
2260  return tf;
2261 }
call make_call(entity a1, list a2)
Definition: ri.c:269
void free_call(call p)
Definition: ri.c:236
bool transformer_weak_consistency_p(transformer t)
Interprocedural transformers do not meet all conditions.
Definition: basic.c:626
transformer transformer_add_variables_update(transformer t, list vl)
Definition: basic.c:340
transformer load_summary_transformer(entity e)
list effects_to_constant_path_effects_with_no_pointer_information(list)
list effect_to_constant_path_effects_with_points_to(effect, statement, transformer)
Definition: eval.c:284
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
statement get_current_statement_from_statement_global_stack(void)
Definition: static.c:344
#define call_arguments(x)
Definition: ri.h:711
transformer any_user_call_site_to_transformer(entity f, list pc, transformer pre, list __attribute__((unused)) ef)
FI: the handling of varargs had to be modified for Semantics/va_arg.c.
transformer substitute_formal_array_elements_in_transformer(transformer tf, entity f, list pc, transformer pre, list ef)
transformer transformer_formal_parameter_projection(entity f, transformer t)
static transformer transformer_filter_subsumed_variables(transformer tf)
The transformer returned for a call site may be too accurate for the caller.
transformer new_substitute_stubs_in_transformer(transformer tf, call c, statement s, bool backward_p)
Definition: points_to.c:417

References any_user_call_site_to_transformer(), call_arguments, copy_transformer(), EFFECT, effect_to_constant_path_effects_with_points_to(), effects_to_constant_path_effects_with_no_pointer_information(), effects_to_transformer(), f(), FOREACH, free_call(), free_transformer(), gen_nconc(), get_bool_property(), get_current_statement_from_statement_global_stack(), list_undefined, load_summary_transformer(), make_call(), new_substitute_stubs_in_transformer(), NIL, pips_assert, pt_to_list_undefined_p(), substitute_formal_array_elements_in_transformer(), transformer_add_variables_update(), transformer_arguments, transformer_combine(), transformer_filter_subsumed_variables(), transformer_formal_parameter_projection(), transformer_temporary_value_projection(), transformer_undefined, and transformer_weak_consistency_p().

Referenced by c_user_function_call_to_transformer(), and user_call_to_transformer().

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

◆ c_user_function_call_to_transformer()

static transformer c_user_function_call_to_transformer ( entity  e,
expression  expr,
transformer  pre 
)
static

The Fortran and C versions are about the same.

Should I revert and unify them, except for t_calle? This could be unified too by calling user_call_to_transformer()? its precondition

if there is no implicit cast

Build a transformer reflecting the call site

Too bad the precondition is not passed down to evaluate the actual argument expressions... To be changed in the C version

Consistency cannot be checked on a non-local transformer

pips_assert("t_equal is consistent", transformer_consistency_p(t_equal));

Combine the effect of the function call and of the equality

Get rid of the temporary representing the function's value

Parameters
expra value
prea call to a function

Definition at line 1165 of file ri_to_transformers.c.

1169 {
1171  syntax s = expression_syntax(expr);
1172  call c = syntax_call(s);
1173  entity f = call_function(c);
1174  list pc = call_arguments(c);
1175  basic rbt = basic_of_call(c, true, true);
1176  //list ef = expression_to_proper_effects(expr);
1178 
1179  pips_debug(8, "begin\n");
1180  pips_assert("s is a call", syntax_call_p(s));
1181 
1182  /* if there is no implicit cast */
1183  // if(same_basic_p(rbt, entity_basic(e))) {
1184  // FI: let's relax the type compatibility between different kinds of
1185  // int and unsigned int... but forget about typedefs...
1186  if(compatible_basic_p(rbt, entity_basic(e))) {
1187  const char* fn = module_local_name(f);
1188  entity rv = FindEntity(fn, fn);
1189  entity orv = entity_undefined;
1190  transformer t_equal = simple_equality_to_transformer(e, rv, false);
1191 
1192  pips_assert("rv is defined",
1193  !entity_undefined_p(rv));
1194 
1195  /* Build a transformer reflecting the call site */
1196  /* Too bad the precondition is not passed down to evaluate the
1197  actual argument expressions... To be changed in the C version*/
1198  t_caller = c_user_call_to_transformer(f, pc, pre, ef);
1199 
1200  ifdebug(8) {
1201  pips_debug(8, "Transformer %p for callee %s:\n",
1202  t_caller, entity_local_name(f));
1203  dump_transformer(t_caller);
1204  }
1205 
1206  /* Consistency cannot be checked on a non-local transformer */
1207  /* pips_assert("t_equal is consistent",
1208  transformer_consistency_p(t_equal)); */
1209 
1210  ifdebug(8) {
1211  pips_debug(8,
1212  "Transformer %p for equality of %s with %s:\n",
1213  t_equal, entity_local_name(e), entity_name (rv));
1214  dump_transformer(t_equal);
1215  }
1216 
1217  /* Combine the effect of the function call and of the equality */
1218  t_caller = transformer_combine(t_caller, t_equal);
1219  free_transformer(t_equal);
1220 
1221  /* Get rid of the temporary representing the function's value */
1223  if(entity_undefined_p(orv))
1224  t_caller = transformer_filter(t_caller, CONS(ENTITY, rv, NIL));
1225  else
1226  t_caller = transformer_filter(t_caller,
1227  CONS(ENTITY, rv, CONS(ENTITY, orv, NIL)));
1228 
1229  ifdebug(8) {
1230  pips_debug(8,
1231  "Final transformer %p for assignment of %s with %s:\n",
1232  t_caller, entity_local_name(e), entity_name(rv));
1233  dump_transformer(t_caller);
1234  }
1235  }
1236  else {
1237  t_caller = effects_to_transformer(ef);
1238  }
1239 
1240  gen_free_list(ef);
1241 
1242  pips_debug(8, "end with t_caller=%p\n", t_caller);
1243 
1244  return t_caller;
1245 }
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
basic entity_basic(entity e)
return the basic associated to entity e if it's a function/variable/constant basic_undefined otherwis...
Definition: entity.c:1380
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
bool compatible_basic_p(basic, basic)
check if two basics are similar.
Definition: type.c:978
basic basic_of_call(call, bool, bool)
basic basic_of_call(call c): returns the basic of the result given by the call "c".
Definition: type.c:1469
#define call_function(x)
Definition: ri.h:709
#define syntax_call(x)
Definition: ri.h:2736
transformer c_user_call_to_transformer(entity f, list pc, transformer pre, list ef)
transformer transformer_filter(transformer t, list args)
transformer transformer_filter(transformer t, cons * args): projection of t along the hyperplane defi...
Definition: transformer.c:1716
entity global_new_value_to_global_old_value(entity)
Definition: value.c:716

References basic_of_call(), c_user_call_to_transformer(), call_arguments, call_function, compatible_basic_p(), CONS, dump_transformer, effects_to_transformer(), ENTITY, entity_basic(), entity_local_name(), entity_name, entity_undefined, entity_undefined_p, expression_syntax, expression_to_proper_constant_path_effects(), f(), FindEntity(), free_transformer(), gen_free_list(), global_new_value_to_global_old_value(), ifdebug, module_local_name(), NIL, pips_assert, pips_debug, simple_equality_to_transformer(), syntax_call, syntax_call_p, transformer_combine(), transformer_filter(), and transformer_undefined.

Referenced by user_function_call_to_transformer().

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

◆ call_to_transformer()

transformer call_to_transformer ( call  c,
transformer  pre,
list  ef 
)

Use to be static, but may be called from expressions in C.

effects of call c

call to an external function; preliminary version: rely on effects

A temporary variable should be allocated and user_function_call_to_transformer() be used. The variable should then be projected to keep only the side effects of the call.

Add information from pre. Invariant information is easy to use. Information about initial values, that is final values in pre, can also be used.

tf = transformer_normalize(tf, 4);

Parameters
prere
eff

Definition at line 1044 of file ri_to_transformers.c.

1047 {
1049  entity e = call_function(c);
1050  cons *pc = call_arguments(c);
1051  tag tt;
1052 
1053  ifdebug(9) {
1054  pips_debug(9,"begin with precondition %p \n", pre);
1055  print_transformer(pre);
1057  ifdebug(9) {
1058  statement curstat = statement_undefined;
1061  if (!statement_undefined_p(curstat))
1062  print_statement(curstat);
1063  }
1064  }
1065 
1066  switch (tt = value_tag(entity_initial(e))) {
1067  case is_value_code:
1068  /* call to an external function; preliminary version:
1069  rely on effects */
1071  type et = ultimate_type(entity_type(e));
1073 
1074  if(type_void_p(rt)) {
1075  tf = user_call_to_transformer(e, pc, pre, ef);
1076  reset_temporary_value_counter(); // might not be a good idea
1077  // with expression lists?
1078  // Get rid of variables that have been subsumed by abstract
1079  // locations
1081  }
1082  else {
1083  if(analyzed_type_p(rt)) {
1084  /* A temporary variable should be allocated and
1085  user_function_call_to_transformer() be used. The variable
1086  should then be projected to keep only the side effects of
1087  the call. */
1089  expression expr = call_to_expression(c);
1090 
1091  tf = user_function_call_to_transformer(trv, expr, pre);
1094  semantics_user_warning("Analyzable result of Function \"%s\" is "
1095  "ignored. Should it be casted to \"(void)\"?\n",
1096  entity_user_name(e));
1097  // Get rid of variables that have been subsumed by abstract
1098  // locations
1100  }
1101  else {
1102  tf = user_call_to_transformer(e, pc, pre, ef);
1103  reset_temporary_value_counter(); // might not be a good idea
1104  semantics_user_warning("Result of function \"%s\" ignored. "
1105  "Should it be casted to \"(void)\"?\n",
1106  entity_user_name(e));
1107  // Get rid of variables that have been subsumed by abstract
1108  // locations
1110  }
1111  }
1112  }
1113  else
1114  tf = effects_to_transformer(ef);
1115  break;
1116  case is_value_symbolic:
1117  case is_value_constant:
1118  tf = transformer_identity();
1119  break;
1120  case is_value_unknown:
1121  pips_internal_error("function %s has an unknown value", entity_name(e));
1122  break;
1123  case is_value_intrinsic:
1124  tf = intrinsic_to_transformer(e, pc, pre, ef);
1125  break;
1126  default:
1127  pips_internal_error("unknown tag %d", tt);
1128  }
1129  pips_assert("transformer tf is consistent",
1131 
1132  ifdebug(8) {
1133  pips_debug(8,"Transformer before intersection with precondition, tf=%p\n",
1134  tf);
1135  (void) print_transformer(tf);
1136  }
1137 
1138  /* Add information from pre. Invariant information is easy to
1139  use. Information about initial values, that is final values in pre,
1140  can also be used. */
1142  ifdebug(8) {
1143  pips_debug(8,"After intersection and before normalization with tf=%p\n", tf);
1144  (void) print_transformer(tf);
1145  }
1146  ifdebug(8) {
1147  pips_debug(8,"with precondition pre=%p\n", pre);
1148  (void) print_transformer(pre);
1149  }
1150 /* tf = transformer_normalize(tf, 4); */
1151  tf = transformer_normalize(tf, 2);
1152 
1153  ifdebug(8) {
1154  pips_debug(8,"end after normalization with tf=%p\n", tf);
1155  (void) print_transformer(tf);
1156  }
1157 
1158  return(tf);
1159 }
#define pips_internal_error
Definition: misc-local.h:149
int tag
TAG.
Definition: newgen_types.h:92
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
#define SEMANTICS_INTERPROCEDURAL
expression call_to_expression(call c)
Build an expression that call a function or procedure.
Definition: expression.c:309
bool statement_global_stack_defined_p(void)
Definition: static.c:364
#define value_tag(x)
Definition: ri.h:3064
@ is_value_intrinsic
Definition: ri.h:3034
@ is_value_unknown
Definition: ri.h:3035
@ is_value_constant
Definition: ri.h:3033
@ is_value_code
Definition: ri.h:3031
@ is_value_symbolic
Definition: ri.h:3032
#define statement_undefined_p(x)
Definition: ri.h:2420
#define statement_undefined
Definition: ri.h:2419
transformer user_function_call_to_transformer(entity e, expression expr, transformer pre)
a function call is a call to a non void function in C and to a FUNCTION in Fortran
transformer user_call_to_transformer(entity f, list pc, transformer pre, list ef)
transformer intrinsic_to_transformer(entity e, list pc, transformer pre, list ef)
effects of intrinsic call
transformer transformer_safe_domain_intersection(transformer tf, transformer pre)
If tf and pre are defined, update tf.
Definition: transformer.c:696

References analyzed_type_p(), call_arguments, call_function, call_to_expression(), effects_to_transformer(), entity_initial, entity_name, entity_type, entity_user_name(), functional_result, get_bool_property(), get_current_statement_from_statement_global_stack(), ifdebug, intrinsic_to_transformer(), is_value_code, is_value_constant, is_value_intrinsic, is_value_symbolic, is_value_unknown, make_local_temporary_value_entity(), pips_assert, pips_debug, pips_internal_error, print_entity_variable(), print_statement(), print_transformer, reset_temporary_value_counter(), SEMANTICS_INTERPROCEDURAL, semantics_user_warning, statement_global_stack_defined_p(), statement_undefined, statement_undefined_p, transformer_consistency_p(), transformer_filter_subsumed_variables(), transformer_identity(), transformer_normalize(), transformer_safe_domain_intersection(), transformer_temporary_value_projection(), transformer_undefined, type_functional, type_void_p, ultimate_type(), user_call_to_transformer(), user_function_call_to_transformer(), and value_tag.

Referenced by expression_to_transformer(), instruction_to_transformer(), and instruction_to_transformer_list().

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

◆ complete_non_identity_statement_transformer()

transformer complete_non_identity_statement_transformer ( transformer  t,
transformer  pre,
statement  s 
)

FI: only implemented for while loops.

Parameters
prere

Definition at line 3685 of file ri_to_transformers.c.

3688 {
3689  return generic_complete_statement_transformer(t, pre, s, false);
3690 }
transformer generic_complete_statement_transformer(transformer t, transformer pre, statement s, bool identity_p)
Loops, do, for, while or repeat, have transformers linked to their body preconditions so as to comput...

References generic_complete_statement_transformer().

+ Here is the call graph for this function:

◆ complete_statement_transformer()

transformer complete_statement_transformer ( transformer  t,
transformer  pre,
statement  s 
)

Returns the effective transformer ct for a given statement s.

t is the stored transformer. For loops, t is useful to compute the body preconditions but not to compute the loop postcondition. ct can be used to compute the statement s postcondition, no matter what kind of statement s is, and to compute the transformer of a higher-level statement enclosing s.

In other words, load_statement_transformer(s) does not always return a transformer which can be composed with another transformer or applied to a precondition. But statement_to_transformer() always returns such a transformer.

Always allocates a new transformer. This probably creates a memory leak when going up the internal representation because it was originally assumed that the transformer returned recursively was also the transformer stored at a lower level. This is changed because this function calls itself recursively. So now statement_to_transformer() returns a transformer which is not the transformer stored for the statement.

Parameters
prere

Definition at line 3677 of file ri_to_transformers.c.

3680 {
3681  return generic_complete_statement_transformer(t, pre, s, true);
3682 }

References generic_complete_statement_transformer().

Referenced by complete_forloop_transformer(), complete_forloop_transformer_list(), complete_repeatloop_transformer_list(), load_completed_statement_transformer(), new_complete_whileloop_transformer_list(), repeatloop_to_postcondition(), statement_to_transformer(), and whileloop_to_postcondition().

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

◆ declaration_to_transformer()

transformer declaration_to_transformer ( entity  v,
transformer  pre 
)

Note: initializations of static variables are not used as transformers but to initialize the program precondition.

It is not assumed that entity_has_values_p(v)==TRUE A write effect on the declared variable is assumed as required by Beatrice Creusillet for region computation.

if(place_holder_variable_p(v)) {

tf = transformer_identity();

}

FI: the initialization expression might have relevant side-effects? This could ba handled by generalizing variable_to_initial_expression() and by returning expression_undefined incase of failure instead of aborting.

Use the dimension expressions and the initial value

add type information because it will not be done later since declarations with no initialization lead to an identity transformer

Parameters
prere

Definition at line 580 of file ri_to_transformers.c.

581 {
583 
584  pips_debug(8, "Transformer for declaration of \"%s\"\n", entity_name(v));
585 
586  // FI: should not be useful here
587  /* if(place_holder_variable_p(v)) { */
588  /* tf = transformer_identity(); */
589  /* } */
590  if(false && !entity_has_values_p(v)) {
591  /* FI: the initialization expression might have relevant
592  side-effects? This could ba handled by generalizing
593  variable_to_initial_expression() and by returning
594  expression_undefined incase of failure instead of aborting. */
595  tf = transformer_identity();
596  }
597  else if(variable_static_p(v)) {
598  if(get_bool_property("SEMANTICS_COMPUTE_TRANSFORMERS_IN_CONTEXT"))
599  tf = transformer_range(pre);
600  else
601  tf = transformer_identity();
602  }
603  else {
604  /* Use the dimension expressions and the initial value */
605  transformer prer = transformer_range(pre);
607  free_transformer(prer);
608  transformer npre = transformer_apply(dt, pre);
609  transformer nr = transformer_range(npre);
611  tf = dt;
612  if(!expression_undefined_p(ie)) {
614  tf = transformer_combine(tf, itf);
615  free_transformer(itf);
616  free_expression(ie);
617  }
618  else {
619  if(entity_has_values_p(v)) {
620  /* add type information because it will not be done later
621  since declarations with no initialization lead to an
622  identity transformer */
623  if(get_bool_property("SEMANTICS_USE_TYPE_INFORMATION")
624  || get_bool_property("SEMANTICS_USE_TYPE_INFORMATION_IN_PRECONDITIONS")) {
626  }
627  }
628  }
629  free_transformer(npre);
630  free_transformer(nr);
631  }
632 
633  pips_assert("tf is defined", !transformer_undefined_p(tf));
634 
635  ifdebug(8) {
636  pips_debug(8, "Ends with:\n");
637  (void) print_transformer(tf);
638  }
639 
640  return tf;
641 }
expression variable_initial_expression(entity)
Returns a copy of the initial (i.e.
Definition: variable.c:1899
bool variable_static_p(entity)
true if v appears in a SAVE statement, or in a DATA statement, or is declared static i C.
Definition: variable.c:1579
#define expression_undefined_p(x)
Definition: ri.h:1224
transformer safe_assigned_expression_to_transformer(entity v, expression expr, transformer pre)
Always returns a fully defined transformer.
transformer dimensions_to_transformer(entity v, transformer pre)
Assumes that entity_has_values_p(v) holds.
void transformer_add_variable_type_information(transformer, entity)
Definition: type.c:168

References dimensions_to_transformer(), entity_has_values_p(), entity_name, expression_undefined_p, free_expression(), free_transformer(), get_bool_property(), ifdebug, pips_assert, pips_debug, print_transformer, safe_assigned_expression_to_transformer(), transformer_add_variable_type_information(), transformer_apply(), transformer_combine(), transformer_identity(), transformer_range(), transformer_undefined, transformer_undefined_p, variable_initial_expression(), and variable_static_p().

Referenced by declarations_to_transformer(), declarations_to_transformer_list(), and propagate_preconditions_in_declarations().

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

◆ declarations_to_transformer()

transformer declarations_to_transformer ( list  dl,
transformer  pre 
)

For C declarations.

Very close to a block_to_transformer() as declarations can be seen as a sequence of assignments.

Note: initialization of static variables are not taken into account. They must be used for summary preconditions.

post = transformer_safe_normalize(post, 4);

post = transformer_safe_normalize(post, 4);

btf = transformer_normalize(btf, 4);

Parameters
dll
prere

Definition at line 649 of file ri_to_transformers.c.

650 {
656  list l = dl;
657 
658  pips_debug(8,"begin\n");
659 
660  if(ENDP(l))
661  btf = transformer_identity();
662  else {
663  v = ENTITY(CAR(l));
665  post = transformer_safe_apply(stf, pre);
666 /* post = transformer_safe_normalize(post, 4); */
667  post = transformer_safe_normalize(post, 2);
668  btf = transformer_dup(stf);
669  for (POP(l) ; !ENDP(l); POP(l)) {
670  v = ENTITY(CAR(l));
671  if(!transformer_undefined_p(next_pre))
672  free_transformer(next_pre);
673  next_pre = transformer_range(post);
674  stf = declaration_to_transformer(v, next_pre);
675  post = transformer_safe_apply(stf, next_pre);
676  free_transformer(next_pre);
677  next_pre = transformer_undefined; // FI: works even without this...
678 /* post = transformer_safe_normalize(post, 4); */
679  post = transformer_safe_normalize(post, 2);
680  btf = transformer_combine(btf, stf);
681 /* btf = transformer_normalize(btf, 4); */
682  btf = transformer_normalize(btf, 2);
683 
684  ifdebug(1)
685  pips_assert("btf is a consistent transformer", transformer_consistency_p(btf));
686  pips_assert("post is a consistent transformer if pre is defined",
688  }
689  free_transformer(post);
690  }
691 
692  pips_debug(8, "end\n");
693  return btf;
694 }
transformer declaration_to_transformer(entity v, transformer pre)
Note: initializations of static variables are not used as transformers but to initialize the program ...

References CAR, declaration_to_transformer(), ENDP, ENTITY, entity_undefined, free_transformer(), ifdebug, pips_assert, pips_debug, POP, stf(), transformer_combine(), transformer_consistency_p(), transformer_dup(), transformer_identity(), transformer_normalize(), transformer_range(), transformer_safe_apply(), transformer_safe_normalize(), transformer_undefined, and transformer_undefined_p.

Referenced by statement_to_postcondition(), statement_to_transformer(), and statement_to_transformer_list().

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

◆ dimensions_to_transformer()

transformer dimensions_to_transformer ( entity  v,
transformer  pre 
)

Assumes that entity_has_values_p(v) holds.

FI: this should be done for all variables, regardless of their types.

Parameters
prere

Definition at line 535 of file ri_to_transformers.c.

536 {
539 
540  if(type_variable_p(vt)) {
541  list dl = variable_dimensions(type_variable(vt)); // dimension list
542  if(!ENDP(dl)) { // to save a copy and to simplify debugging
543  transformer cpre = copy_transformer(pre);
544 
545  FOREACH(DIMENSION, d, dl) {
549  transformer lpre = transformer_apply(lt, pre);
550  transformer lpre_r = transformer_range(lpre);
552  transformer upre = transformer_apply(ut, lpre);
553 
554  free_transformer(cpre);
555  cpre = transformer_range(upre);
556  free_transformer(upre);
557  free_transformer(lpre);
558  free_transformer(lpre_r);
559 
560  dt = transformer_combine(transformer_combine(dt, lt), ut);
561  free_transformer(lt);
562  free_transformer(ut);
563  }
564  free_transformer(cpre);
565  }
566  else {
567  // FI: equivalent to copy_transformer(pre) I believe
568  dt = transformer_apply(dt, pre);
569  }
570  }
571 
572  return dt;
573 }
#define dimension_lower(x)
Definition: ri.h:980
#define dimension_upper(x)
Definition: ri.h:982

References copy_transformer(), DIMENSION, dimension_lower, dimension_upper, ENDP, entity_basic_concrete_type(), FOREACH, free_transformer(), safe_expression_to_transformer(), transformer_apply(), transformer_combine(), transformer_identity(), transformer_range(), type_variable, type_variable_p, and variable_dimensions.

Referenced by declaration_to_transformer(), and declaration_to_transformer_list().

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

◆ effects_to_arguments()

list effects_to_arguments ( list  fx)

list of effects

algorithm: keep only write effects on scalar variable with values

Parameters
fxx

Definition at line 798 of file ri_to_transformers.c.

799 {
800  /* algorithm: keep only write effects on scalar variable with values */
801  list args = NIL;
802 
803  FOREACH(EFFECT, ef, fx) {
805  action a = effect_action(ef);
806  entity e = reference_variable(r);
807 
808  if(action_write_p(a) && entity_has_values_p(e)) {
809  args = arguments_add_entity(args, e);
810  }
811  }
812 
813  return args;
814 }
cons * arguments_add_entity(cons *a, entity e)
Definition: arguments.c:85
#define effect_action(x)
Definition: effects.h:642
#define action_write_p(x)
Definition: effects.h:314

References action_write_p, arguments_add_entity(), EFFECT, effect_action, effect_any_reference, entity_has_values_p(), FOREACH, NIL, and reference_variable.

+ Here is the call graph for this function:

◆ effects_to_transformer()

transformer effects_to_transformer ( list  e)

list of effects

Definition at line 474 of file ri_to_transformers.c.

475 {
478  return tf;
479 }
static transformer apply_effects_to_transformer(transformer tf, list el, bool apply_p, expression rhs)

References apply_effects_to_transformer(), expression_undefined, and transformer_identity().

Referenced by add_good_loop_conditions(), add_loop_index_initialization(), any_assign_to_transformer_list(), any_basic_update_to_transformer(), any_basic_update_to_transformer_list(), any_loop_to_k_transformer(), any_scalar_assign_to_transformer(), any_scalar_assign_to_transformer_list(), any_update_to_transformer(), any_update_to_transformer_list(), any_user_call_site_to_transformer(), c_return_to_transformer(), c_user_call_to_transformer(), c_user_function_call_to_transformer(), call_to_transformer(), condition_to_transformer(), conditional_to_transformer(), expression_effects_to_transformer(), expression_to_transformer(), fortran_user_call_to_transformer(), integer_assign_to_transformer(), integer_assign_to_transformer_list(), intrinsic_to_transformer(), intrinsic_to_transformer_list(), load_summary_transformer(), loop_to_transformer(), new_loop_to_transformer(), process_ready_node(), safe_any_expression_to_transformer(), standard_whileloop_to_transformer(), test_to_transformer(), test_to_transformer_list(), unstructured_to_transformer(), and user_call_to_transformer().

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

◆ filter_transformer()

transformer filter_transformer ( transformer  t,
list  e 
)

Previous version of effects_to_transformer() transformer effects_to_transformer(list e) { list args = NIL; Pbase b = VECTEUR_NUL; Psysteme s = sc_new();.

s->base = b; s->dimension = vect_size(b);

return make_transformer(args, make_predicate(s)); }

algorithm: keep only information about scalar variables with values appearing in effects e and store it into a newly allocated transformer

action a = effect_action(ef);

action_write_p(a) &&

I do not know yet if I should keep old values...

FI: I should check if sc is sc_empty but I haven't (yet) found a cheap syntactic test

Definition at line 495 of file ri_to_transformers.c.

496 {
497  /* algorithm: keep only information about scalar variables with values
498  * appearing in effects e and store it into a newly allocated transformer
499  */
500  Pbase b = VECTEUR_NUL;
501  Psysteme s = SC_UNDEFINED;
503  list args = NIL;
505 
506  FOREACH(EFFECT, ef, e) {
508  /* action a = effect_action(ef); */
509  entity v = reference_variable(r);
510 
511  if(/* action_write_p(a) && */ entity_has_values_p(v)) {
512  /* I do not know yet if I should keep old values... */
513  entity new_val = entity_to_new_value(v);
514  b = vect_add_variable(b, (Variable) new_val);
515 
517  args = arguments_add_entity(args, v);
518  }
519  }
520  }
521 
522  /* FI: I should check if sc is sc_empty but I haven't (yet) found a
523  cheap syntactic test */
525 
526  return make_transformer(args, make_predicate(s));
527 }
transformer make_transformer(list a1, predicate a2)
Definition: ri.c:2649
predicate make_predicate(Psysteme a1)
Definition: ri.c:1820
Pbase vect_add_variable(Pbase b, Variable v)
package vecteur - routines sur les bases
Definition: base.c:61
Psysteme sc_restricted_to_variables_transitive_closure(Psysteme sc, Pbase variables)
for an improved dependence test (Beatrice Creusillet)
Definition: sc_misc.c:64
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
#define VECTEUR_NUL
DEFINITION DU VECTEUR NUL.

References arguments_add_entity(), EFFECT, effect_any_reference, entity_has_values_p(), entity_is_argument_p(), entity_to_new_value(), FOREACH, make_predicate(), make_transformer(), NIL, predicate_system, reference_variable, sc_restricted_to_variables_transitive_closure(), transformer_arguments, transformer_relation, vect_add_variable(), and VECTEUR_NUL.

Referenced by semantic_to_text().

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

◆ fortran_user_call_to_transformer()

transformer fortran_user_call_to_transformer ( entity  f,
list  pc,
list  ef 
)

Effects are necessary to clean up the transformer t_caller.

For instance, an effect on variable X may not be taken into account in t_callee but it may be equivalenced thru a common to a variable i which is analyzed in the caller. If X is written, I value is lost. See Validation/equiv02.f.

add equations linking formal parameters to argument expressions to transformer t_callee and project along the formal parameters

for performance, it would be better to avoid building formals and to inline entity_to_formal_parameters

it wouls also be useful to distinguish between in and out parameters; I'm not sure the information is really available in a field ???

take care of analyzable formal parameters

type checking. You already know that fp is a scalar variable

formal parameter e is modified. expr must be a reference

normal case: ap_new==fp_new, ap_old==fp_old

Variable ap is not analyzed. The information about fp will be lost.

Attemps at modifying a value: expr is call, fp is modified

Actual argument is not a reference: it might be a user error! Transformers do not carry the may/must information. A check with effect list ef should be performed...

FI: does effect computation emit a MUST/MAYwarning?

Formal parameter fp is not modified. Add fp == expr, if possible.

We should evaluate expr under a precondition pre... which has not been passed down. We set pre==tf_undefined.

temporary value counter cannot be reset because other temporary values may be in use in a case the user call is a user function call

reset_temporary_value_counter();

formal new and old values left over are eliminated

test to insure that entity_to_old_value exists

take care of global variables

FI: are invisible variables taken care of by translate_global_values()? Yes, now... A variable may be invisible because its location is reached thru an array or thru a non-integer scalar variable in the current module, for instance because a COMMON is defined differently. A variable whose location is not reachable in the current module environment is considered visible.

Callee f may have read/write effects on caller's scalar integer variables thru an array and/or non-integer variables.

The relation basis must be updated too

The return value of a function is not yet projected.

Parameters
pcc
eff

Definition at line 2269 of file ri_to_transformers.c.

2272 {
2275  transformer t_effects = transformer_undefined;
2276  entity caller = entity_undefined;
2277  list all_args = list_undefined;
2278 
2279  pips_debug(8, "begin\n");
2280 
2281  /* add equations linking formal parameters to argument expressions
2282  to transformer t_callee and project along the formal parameters */
2283  /* for performance, it would be better to avoid building formals
2284  and to inline entity_to_formal_parameters */
2285  /* it wouls also be useful to distinguish between in and out
2286  parameters; I'm not sure the information is really available
2287  in a field ??? */
2289  list formals_new = NIL;
2290 
2291  t_callee = load_summary_transformer(f);
2292 
2293  ifdebug(8) {
2294  Psysteme s =
2296  pips_debug(8, "Transformer for callee %s:\n",
2297  entity_local_name(f));
2298  dump_transformer(t_callee);
2299  sc_fprint(stderr, s, (char * (*)(Variable)) dump_value_name);
2300  }
2301 
2302  t_caller = transformer_dup(t_callee);
2303 
2304  /* take care of analyzable formal parameters */
2305 
2306  FOREACH(ENTITY, fp, formals) {
2308  expression expr = find_ith_argument(pc, r);
2309 
2310  if(expr == expression_undefined)
2311  pips_user_error("not enough args for %d formal parm."
2312  " %s in call to %s from %s\n",
2315  else {
2316  /* type checking. You already know that fp is a scalar variable */
2317  type tfp = entity_type(fp);
2318  basic bfp = variable_basic(type_variable(tfp));
2319  basic bexpr = basic_of_expression(expr);
2320  //list l_eff = expression_to_proper_effects(expr);
2322 
2323  if(effects_write_at_least_once_p(l_eff)) {
2324  semantics_user_warning("Side effects in actual arguments are not yet taken into account\n."
2325  "Meanwhile, \"atomize\" the call site to avoid the problem.\n");
2326  }
2327  gen_free_list(l_eff);
2328 
2329  if(!basic_equal_p(bfp, bexpr)) {
2330  semantics_user_warning("Type incompatibility (formal %s/actual %s) "
2331  "for formal parameter \"%s\" (rank %d) "
2332  "in call to \"%s\" from \"%s\"\n",
2333  basic_to_string(bfp), basic_to_string(bexpr),
2336  continue;
2337  }
2338  }
2339 
2340  if(entity_is_argument_p(fp, transformer_arguments(t_callee))) {
2341  /* formal parameter e is modified. expr must be a reference */
2342  syntax sexpr = expression_syntax(expr);
2343 
2344  if(syntax_reference_p(sexpr)) {
2346 
2347  if(entity_has_values_p(ap)) {
2349  entity ap_new = entity_to_new_value(ap);
2350  entity ap_old = entity_to_old_value(ap);
2351 
2352  if(base_contains_variable_p(s->base, (Variable) ap_new)) {
2354  "Variable %s seems to be aliased thru variable %s"
2355  " at a call site to %s in %s\n"
2356  "PIPS semantics analysis assumes no aliasing as"
2357  " imposed by the Fortran standard.\n",
2358  entity_name(fp),
2359  entity_name(value_to_variable(ap_new)),
2362  }
2363  else { /* normal case: ap_new==fp_new, ap_old==fp_old */
2364  entity fp_new = external_entity_to_new_value(fp);
2365  entity fp_old = external_entity_to_old_value(fp);
2366 
2367  t_caller = transformer_value_substitute
2368  (t_caller, fp_new, ap_new);
2369  t_caller = transformer_value_substitute
2370  (t_caller, fp_old, ap_old);
2371  }
2372  }
2373  else { /* Variable ap is not analyzed. The information about fp
2374  will be lost. */
2375  ;
2376  }
2377  }
2378  else {
2379  /* Attemps at modifying a value: expr is call, fp is modified */
2380  /* Actual argument is not a reference: it might be a user error!
2381  * Transformers do not carry the may/must information.
2382  * A check with effect list ef should be performed...
2383  *
2384  * FI: does effect computation emit a MUST/MAYwarning?
2385  */
2386  entity fp_new = external_entity_to_new_value(fp);
2387  entity fp_old = external_entity_to_old_value(fp);
2388  list args = arguments_add_entity(arguments_add_entity(NIL, fp_new), fp_old);
2389 
2390  semantics_user_warning("value (!) might be modified by call to %s\n"
2391  "%dth formal parameter %s\n",
2393  t_caller = transformer_filter(t_caller, args);
2394  free_arguments(args);
2395  }
2396  }
2397  else {
2398  /* Formal parameter fp is not modified. Add fp == expr, if possible. */
2399  /* We should evaluate expr under a precondition pre... which has
2400  not been passed down. We set pre==tf_undefined. */
2401  entity fp_new = external_entity_to_new_value(fp);
2402  transformer t_expr = any_expression_to_transformer(fp_new, expr,
2404  false);
2405 
2406  if(!transformer_undefined_p(t_expr)) {
2407  t_expr = transformer_temporary_value_projection(t_expr);
2408  /* temporary value counter cannot be reset because other
2409  temporary values may be in use in a case the user call is a
2410  user function call */
2411  /* reset_temporary_value_counter(); */
2412  t_caller = transformer_safe_image_intersection(t_caller, t_expr);
2413  free_transformer(t_expr);
2414  }
2415  }
2416  }
2417 
2418  pips_debug(8, "Before formal new values left over are eliminated\n");
2419  ifdebug(8) dump_transformer(t_caller);
2420 
2421  /* formal new and old values left over are eliminated */
2422  FOREACH(ENTITY, e, formals) {
2424  formals_new = CONS(ENTITY, e_new, formals_new);
2425  /* test to insure that entity_to_old_value exists */
2426  if(entity_is_argument_p(e_new,
2427  transformer_arguments(t_caller))) {
2429  formals_new = CONS(ENTITY, e_old, formals_new);
2430  }
2431  }
2432 
2433  t_caller = transformer_filter(t_caller, formals_new);
2434 
2435  free_arguments(formals_new);
2436  free_arguments(formals);
2437 
2438  ifdebug(8) {
2440  pips_debug(8,
2441  "After binding formal/real parameters and eliminating formals\n");
2442  dump_transformer(t_caller);
2443  sc_fprint(stderr, s, (char * (*)(Variable)) dump_value_name);
2444  }
2445 
2446  /* take care of global variables */
2447  caller = get_current_module_entity();
2448  translate_global_values(caller, t_caller);
2449 
2450  /* FI: are invisible variables taken care of by translate_global_values()?
2451  * Yes, now...
2452  * A variable may be invisible because its location is reached
2453  * thru an array or thru a non-integer scalar variable in the
2454  * current module, for instance because a COMMON is defined
2455  * differently. A variable whose location is not reachable
2456  * in the current module environment is considered visible.
2457  */
2458 
2459  ifdebug(8) {
2460  pips_debug(8, "After replacing global variables\n");
2461  dump_transformer(t_caller);
2462  }
2463 
2464  if(!transformer_empty_p(t_caller)) {
2465  /* Callee f may have read/write effects on caller's scalar
2466  * integer variables thru an array and/or non-integer variables.
2467  */
2468  t_effects = effects_to_transformer(ef);
2469  all_args = arguments_union(transformer_arguments(t_caller),
2470  transformer_arguments(t_effects));
2471  /*
2472  free_transformer(t_effects);
2473  gen_free_list(transformer_arguments(t_caller));
2474  */
2475  transformer_arguments(t_caller) = all_args;
2476  /* The relation basis must be updated too */
2477  FOREACH(ENTITY, v, transformer_arguments(t_effects)) {
2479  sc_base_add_variable(sc, (Variable) v);
2480  }
2481  }
2482  else {
2483  semantics_user_warning("Call to %s seems never to return."
2484  " This may be due to an infinite loop in %s,"
2485  " or to a systematic exit in %s,"
2486  " or to standard violations (see previous messages)\n",
2489  module_local_name(f));
2490  }
2491 
2492  ifdebug(8) {
2493  pips_debug(8,
2494  "End: after taking all scalar effects in consideration %p\n",
2495  t_caller);
2496  dump_transformer(t_caller);
2497  }
2498 
2499  /* The return value of a function is not yet projected. */
2500  pips_assert("transformer t_caller is consistent",
2501  transformer_weak_consistency_p(t_caller));
2502 
2503  return t_caller;
2504 }
cons * arguments_union(cons *a1, cons *a2)
cons * arguments_union(cons * a1, cons * a2): returns a = union(a1, a2) where a1 and a2 are lists of ...
Definition: arguments.c:116
void free_arguments(cons *args)
Definition: arguments.c:218
bool base_contains_variable_p(Pbase b, Variable v)
bool base_contains_variable_p(Pbase b, Variable v): returns true if variable v is one of b's elements...
Definition: base.c:136
bool effects_write_at_least_once_p(list)
const char * get_current_module_name(void)
Get the name of the current module.
Definition: static.c:121
char * dump_value_name(entity e)
char * dump_value_name(e): used as functional argument because entity_name is a macro
Definition: io.c:128
expression find_ith_argument(list args, int n)
Definition: expression.c:1147
bool basic_equal_p(basic, basic)
Definition: type.c:927
#define formal_offset(x)
Definition: ri.h:1408
#define entity_storage(x)
Definition: ri.h:2794
#define storage_formal(x)
Definition: ri.h:2524
struct Ssysteme * Psysteme
void sc_base_add_variable(Psysteme sc, Variable var)
Definition: sc.c:248
void sc_fprint(FILE *fp, Psysteme ps, get_variable_name_t nom_var)
void sc_fprint(FILE * f, Psysteme ps, char * (*nom_var)()): cette fonction imprime dans le fichier po...
Definition: sc_io.c:220
void translate_global_values(entity m, transformer tf)
list module_to_formal_analyzable_parameters(entity f)
returns a module's parameter's list
Pbase base
Definition: sc-local.h:75
bool transformer_empty_p(transformer t)
If true is returned, the transformer certainly is empty.
Definition: transformer.c:2455
transformer transformer_safe_image_intersection(transformer t1, transformer t2)
Allocate a new transformer.
Definition: transformer.c:647
entity external_entity_to_new_value(entity)
Definition: value.c:1411
entity external_entity_to_old_value(entity)
Definition: value.c:1422

References any_expression_to_transformer(), arguments_add_entity(), arguments_union(), Ssysteme::base, base_contains_variable_p(), basic_equal_p(), basic_of_expression(), basic_to_string(), CONS, dump_transformer, dump_value_name(), effects_to_transformer(), effects_write_at_least_once_p(), ENTITY, entity_has_values_p(), entity_is_argument_p(), entity_local_name(), entity_name, entity_storage, entity_to_new_value(), entity_to_old_value(), entity_type, entity_undefined, expression_syntax, expression_to_proper_constant_path_effects(), expression_undefined, external_entity_to_new_value(), external_entity_to_old_value(), f(), find_ith_argument(), FOREACH, formal_offset, free_arguments(), free_transformer(), gen_free_list(), get_current_module_entity(), get_current_module_name(), ifdebug, list_undefined, load_summary_transformer(), module_local_name(), module_to_formal_analyzable_parameters(), NIL, pips_assert, pips_debug, pips_user_error, predicate_system, reference_variable, sc_base_add_variable(), sc_fprint(), semantics_user_warning, storage_formal, syntax_reference, syntax_reference_p, transformer_arguments, transformer_dup(), transformer_empty_p(), transformer_filter(), transformer_relation, transformer_safe_image_intersection(), transformer_temporary_value_projection(), transformer_undefined, transformer_undefined_p, transformer_value_substitute(), transformer_weak_consistency_p(), translate_global_values(), type_variable, value_to_variable(), and variable_basic.

Referenced by fortran_user_function_call_to_transformer(), and user_call_to_transformer().

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

◆ fortran_user_function_call_to_transformer()

static transformer fortran_user_function_call_to_transformer ( entity  e,
expression  expr,
transformer __attribute__((unused))  pre 
)
static

its precondition

if(basic_int_p(rbt)) {

Build a transformer reflecting the call site

Too bad the precondition is not passed down to evaluate the actual argument expressions... To be changed in the C version

Build a transformer representing the equality of the function value to e

Consistency cannot be checked on a non-local transformer

pips_assert("t_equal is consistent", transformer_consistency_p(t_equal));

Combine the effect of the function call and of the equality

Get rid of the temporary representing the function's value

FI: e is added in arguments because user_call_to_transformer() uses effects to make sure arrays and non scalar integer variables impact is taken into account

FI, FI: il vaudrait mieux ne pas eliminer e d'abord1

J'ai aussi des free a decommenter

Not checkable with temporary variables pips_assert("transformer t_caller is consistent", transformer_consistency_p(t_caller));

Parameters
expra value
prea call to a function

Definition at line 1248 of file ri_to_transformers.c.

1252 {
1253  syntax s = expression_syntax(expr);
1254  call c = syntax_call(s);
1255  entity f = call_function(c);
1256  list pc = call_arguments(c);
1258  basic rbt = basic_of_call(c, true, true);
1259  //list ef = expression_to_proper_effects(expr);
1261 
1262  pips_debug(8, "begin\n");
1263  pips_assert("s is a call", syntax_call_p(s));
1264 
1265  /* if(basic_int_p(rbt)) { */
1267  const char* fn = module_local_name(f);
1268  entity rv = FindEntity(fn, fn);
1269  entity orv = entity_undefined;
1270  Psysteme sc = SC_UNDEFINED;
1274 
1275  pips_assert("rv is defined",
1276  !entity_undefined_p(rv));
1277 
1278  /* Build a transformer reflecting the call site */
1279  /* Too bad the precondition is not passed down to evaluate the
1280  actual argument expressions... To be changed in the C version*/
1281  t_caller = fortran_user_call_to_transformer(f, pc, ef);
1282 
1283  ifdebug(8) {
1284  pips_debug(8, "Transformer %p for callee %s:\n",
1285  t_caller, entity_local_name(f));
1286  dump_transformer(t_caller);
1287  }
1288 
1289  /* Build a transformer representing the equality of
1290  * the function value to e
1291  */
1292  eq = vect_make(eq,
1293  (Variable) e, VALUE_ONE,
1294  (Variable) rv, VALUE_MONE,
1295  TCST, VALUE_ZERO);
1296  c = contrainte_make(eq);
1297  sc = sc_make(c, CONTRAINTE_UNDEFINED);
1298  t_equal = make_transformer(NIL,
1299  make_predicate(sc));
1300 
1301  /* Consistency cannot be checked on a non-local transformer */
1302  /* pips_assert("t_equal is consistent",
1303  transformer_consistency_p(t_equal)); */
1304 
1305  ifdebug(8) {
1306  pips_debug(8,
1307  "Transformer %p for equality of %s with %s:\n",
1308  t_equal, entity_local_name(e), entity_name (rv));
1309  dump_transformer(t_equal);
1310  }
1311 
1312  /* Combine the effect of the function call and of the equality */
1313  t_caller = transformer_combine(t_caller, t_equal);
1314  free_transformer(t_equal);
1315 
1316  /* Get rid of the temporary representing the function's value */
1318  if(entity_undefined_p(orv))
1319  t_caller = transformer_filter(t_caller, CONS(ENTITY, rv, NIL));
1320  else
1321  t_caller = transformer_filter(t_caller,
1322  CONS(ENTITY, rv, CONS(ENTITY, orv, NIL)));
1323 
1324 
1325  ifdebug(8) {
1326  pips_debug(8,
1327  "Final transformer %p for assignment of %s with %s:\n",
1328  t_caller, entity_local_name(e), entity_name(rv));
1329  dump_transformer(t_caller);
1330  }
1331 
1332  /* FI: e is added in arguments because user_call_to_transformer()
1333  * uses effects to make sure arrays and non scalar integer variables
1334  * impact is taken into account
1335  */
1336  /*
1337  transformer_arguments(t_caller) =
1338  arguments_rm_entity(transformer_arguments(t_caller), e);
1339  */
1340 
1341  /* FI, FI: il vaudrait mieux ne pas eliminer e d'abord1 */
1342  /* J'ai aussi des free a decommenter */
1343  /*
1344  if(ENDP(transformer_arguments(t_caller))) {
1345  transformer_arguments(t_caller) =
1346  gen_nconc(transformer_arguments(t_caller), CONS(ENTITY, e, NIL));
1347  }
1348  else {
1349  t_caller = transformer_value_substitute(t_caller, rv, e);
1350  }
1351  */
1352  /* Not checkable with temporary variables
1353  pips_assert("transformer t_caller is consistent",
1354  transformer_consistency_p(t_caller));
1355  */
1356  }
1357  else {
1358  pips_assert("transformer t_caller is undefined",
1359  transformer_undefined_p(t_caller));
1360  }
1361 
1362  gen_free_list(ef);
1363 
1364  pips_debug(8, "end with t_caller=%p\n", t_caller);
1365 
1366 
1367  return t_caller;
1368 }
#define VALUE_ZERO
#define VALUE_MONE
#define VALUE_ONE
#define CONTRAINTE_UNDEFINED
Pcontrainte contrainte_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
transformer fortran_user_call_to_transformer(entity f, list pc, list ef)
Effects are necessary to clean up the transformer t_caller.
Psysteme sc_make(Pcontrainte leg, Pcontrainte lineg)
Psysteme sc_make(Pcontrainte leg, Pcontrainte lineg): allocation et initialisation d'un systeme d'equ...
Definition: sc.c:78
Pcontrainte eq
element du vecteur colonne du systeme donne par l'analyse
Definition: sc_gram.c:108
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
Pvecteur vect_make(Pvecteur v, Variable var, Value val,...)
Pvecteur vect_make(v, [var, val,]* 0, val) Pvecteur v; // may be NULL, use assigne anyway Variable va...
Definition: alloc.c:165

References basic_equal_p(), basic_of_call(), call_arguments, call_function, CONS, contrainte_make(), CONTRAINTE_UNDEFINED, dump_transformer, ENTITY, entity_local_name(), entity_name, entity_type, entity_undefined, entity_undefined_p, eq, expression_syntax, expression_to_proper_constant_path_effects(), f(), FindEntity(), fortran_user_call_to_transformer(), free_transformer(), gen_free_list(), global_new_value_to_global_old_value(), ifdebug, make_predicate(), make_transformer(), module_local_name(), NIL, pips_assert, pips_debug, sc_make(), syntax_call, syntax_call_p, TCST, transformer_combine(), transformer_filter(), transformer_undefined, transformer_undefined_p, type_variable, VALUE_MONE, VALUE_ONE, VALUE_ZERO, variable_basic, vect_make(), and VECTEUR_NUL.

Referenced by user_function_call_to_transformer().

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

◆ forward_substitute_array_location_in_transformer()

static transformer forward_substitute_array_location_in_transformer ( transformer  tf,
entity  al,
reference  ar,
reference  alr,
entity  fpv 
)
static

Compute the subscript list suffix in the abstract location reference alr with respect to the actual reference ar and use this subscript list to generate a new reference with fpv.

This is used to translate preconditions from call site to callee.

For instance, let s be a struct and a a field of s that is an array. ar is s[a] and alr is s[a][3]. Then we try to substitute the location entity al by the locatio nentity for reference fa[3], where fa is the formal array associated to s[a].

Caller:

struct {int a[10];} s; foo(s.a);

Callee:

void foo(int fa[10])

We need to check that ar and alr have the same prefix of subscripts since the same array can be used several times as an argument, even without aliasing

We build a reference with fpv and the remaining subscripts in asl

Definition at line 1834 of file ri_to_transformers.c.

1835 {
1836  /* We need to check that ar and alr have the same prefix of
1837  * subscripts since the same array can be used several times as
1838  * an argument, even without aliasing
1839  */
1840  list asl = reference_indices(ar);
1841  list alsl = reference_indices(alr);
1842  bool mismatch_p = false;
1843  while(!ENDP(asl) && !ENDP(alsl) && !mismatch_p) {
1844  expression as = EXPRESSION(CAR(asl));
1845  expression als = EXPRESSION(CAR(alsl));
1846  mismatch_p = !expression_equal_p(as, als);
1847  POP(asl), POP(alsl);
1848  }
1849  if(!mismatch_p && ENDP(asl)) {
1850  /* We build a reference with fpv and the remaining
1851  subscripts in asl */
1852  reference fr = make_reference(fpv, gen_full_copy_list(alsl));
1854  if(entity_undefined_p(fl)) {
1855  semantics_user_warning("Untranslatable reference \"%s\" because of"
1856  " imprecise effects.\n",
1857  reference_to_string(fr));
1858  }
1859  else {
1860  list pl = NIL;
1861  tf = substitute_scalar_stub_in_transformer(tf, fl, al, false, &pl);
1862  if(ENDP(pl)) {
1863  ;
1864  }
1865  else {
1866  semantics_user_warning("Translation issues\n.");
1867  gen_free_list(pl);
1868  }
1869  }
1870  free_reference(fr);
1871  }
1872  return tf;
1873 }
list gen_full_copy_list(list l)
Copy a list structure with element copy.
Definition: list.c:535
bool expression_equal_p(expression e1, expression e2)
Syntactic equality e1==e2.
Definition: expression.c:1347
transformer substitute_scalar_stub_in_transformer(transformer tf, entity se, entity de, bool backward_p, list *ppl)
If both "se", source entity, and "de", destination entity, are defined, substitute the values of "se"...
Definition: points_to.c:136

References CAR, constant_memory_access_path_to_location_entity(), ENDP, entity_undefined_p, EXPRESSION, expression_equal_p(), free_reference(), gen_free_list(), gen_full_copy_list(), make_reference(), NIL, pl, POP, reference_indices, reference_to_string(), semantics_user_warning, and substitute_scalar_stub_in_transformer().

Referenced by new_array_elements_forward_substitution_in_transformer().

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

◆ generic_apply_effect_to_transformer()

static transformer generic_apply_effect_to_transformer ( transformer  tf,
effect  e,
bool  apply_p,
expression  rhs,
bool  additional_p 
)
static

Apply or add an effect e on a transformer tf only a write effect has an impact

Parameters
tftransformer
ea write effect on the store (check performed by the caller)
apply_pif we apply or add an effect, true if we apply
rhsredundant with apply_p
additional_pneglect effects that are already expressed by the transformer arguments
Returns
transformer updated with the effect

This function is used in two different contexts: either some information exists in tf and it must be fixed according to the added effect (apply_p==true), or tf contains no information but its argument list and the effect only impact this argument list (appy_p==false)

The old check on static should be useless because already taken into account when effects are computed. And it is harmful here since most effects on static variables cannot be ignored.

FI: this does not mean that l is analyzed in the current module if l is linked to a global variable. The global variable may be analyzed in one module and not in another one because its use is hidden by an anywhere effect. Hence, the check below with entity_has_values_p().

For safety, should this test be included in analyzed_reference_p() or in constant_memory_path_to_location_entity()?

Should we kept the check separated for interprocedural treatments?

FI: this is not precise enough because conflicts are tested at the entity level not at the reference level: see Ticket 842.

Definition at line 303 of file ri_to_transformers.c.

304 {
305  ifdebug(9) {
306  pips_debug(9, "Begin\n");
307  (void) print_transformer(tf);
308  }
310  entity v = reference_variable(r);
311  entity l = entity_undefined; // location impacted
312 
314 
315  /* The old check on static should be useless because already taken
316  * into account when effects are computed. And it is harmful here
317  * since most effects on static variables cannot be ignored.
318  */
319 
320  if(entity_has_values_p(v)) {
321  l = v;
322  }
324  /* FI: this does not mean that l is analyzed in the current module
325  * if l is linked to a global variable. The global variable may be
326  * analyzed in one module and not in another one because its use
327  * is hidden by an anywhere effect. Hence, the check below with
328  * entity_has_values_p().
329  *
330  * For safety, should this test be included
331  * in analyzed_reference_p() or in
332  * constant_memory_path_to_location_entity()?
333  *
334  * Should we kept the check separated for interprocedural treatments?
335  */
337  }
338 
339  pips_debug(9, "\"concrete\" effect\n"); // FI: can be abstract
340 
342  if (apply_p
343  //&& !expression_undefined_p(rhs) // NL : apply_p=false <-> rhs=expression_undefined
344  ) {
345  // NL : case *p=v
346  // FI: the computation of l has to be redone...
347  if(!additional_p || !entity_is_argument_p(l, transformer_arguments(tf)))
348  tf = apply_concrete_effect_to_transformer(tf, e, rhs);
349  }
350  else {
351  // NL : general case, don't understand what exactly we do in this case (what kind of case it is)
352  // NL : transformer_add_variable_update need to be complete
353  // not sure if we have to use transformer_add_variable_update or transformer_add_value_update
354  if(!additional_p || !entity_is_argument_p(l, transformer_arguments(tf)))
356  //transformer_add_value_update(tf, v);
357  }
358  }
359 
361  pips_debug(9, "abstract effect\n");
362  tf = apply_abstract_effect_to_transformer(tf, e, apply_p);
363  }
365  pips_debug(9, "array effect\n");
366  /* FI: this is not precise enough because conflicts are tested at
367  * the entity level not at the reference level: see Ticket 842.
368  */
369  // tf = apply_abstract_effect_to_transformer(tf, e, apply_p);
370  tf = apply_array_effect_to_transformer(tf, e, apply_p);
371  }
372 
373  ifdebug(9) {
374  (void) print_transformer(tf);
375  pips_debug(9, "Ends\n");
376  }
377  return tf;
378 }
bool entity_abstract_location_p(entity al)
bool reference_with_unbounded_subscript_p(reference r)
See if the reference uses the unbounded function '*'.
Definition: expression.c:3085
transformer apply_array_effect_to_transformer(transformer tf, effect e __attribute__((unused)), bool apply_p __attribute__((unused)))
Effect e is assumed to be a memory write effect on an array element location.
static transformer apply_concrete_effect_to_transformer(transformer tf, effect e, expression __attribute__((unused)) rhs)
semantical analysis
static transformer apply_abstract_effect_to_transformer(transformer tf, effect e, bool apply_p)

References analyzed_reference_p(), apply_abstract_effect_to_transformer(), apply_array_effect_to_transformer(), apply_concrete_effect_to_transformer(), constant_memory_access_path_to_location_entity(), constant_path_analyzed_p(), effect_any_reference, entity_abstract_location_p(), entity_has_values_p(), entity_is_argument_p(), entity_undefined, entity_undefined_p, ifdebug, pips_debug, print_entity_variable(), print_transformer, reference_variable, reference_with_unbounded_subscript_p(), transformer_add_variable_update(), and transformer_arguments.

Referenced by generic_apply_effects_to_transformer().

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

◆ generic_apply_effects_to_transformer()

static transformer generic_apply_effects_to_transformer ( transformer  tf,
list  el,
bool  apply_p,
expression  rhs,
bool  additional_p,
bool  abstract_p 
)
static

These two functions are not currently used static transformer apply_effect_to_transformer(transformer tf, effect e, bool apply_p, expression rhs) { return generic_apply_effect_to_transformer(tf, e, apply_p, rhs, false); }.

static transformer apply_additional_effect_to_transformer(transformer tf, effect e, bool apply_p, expression rhs) { return generic_apply_effect_to_transformer(tf, e, apply_p, rhs, true); } old name add_effects_to_transformer

Make sure that all variables modified according to the effect list e and taken into account by the semantics analysis is an argument of tf and that the corresponding variables are declared in the basis.

No allocation, just a side effect on tf.

Apply or add a list of effect el on a transformer tf. Only the write effects are taken into account. A normalized empty transformer is not modified.

Parameters
tftransformer (modified by side effect)
ellist of effects
apply_pif we apply or add the list of effect, true if we apply
rhs
additional_pdo not rewrite variables that have already been modified in tf
abstract_ponly exploit abstract effects
Returns
transformer with the effects

algorithm: keep only memory write effects on variables with values

Definition at line 414 of file ri_to_transformers.c.

415 {
416  ifdebug(9) {
417  pips_debug(9, "Begin\n");
418  (void) print_transformer(tf);
419  }
420 
421  if(!transformer_is_empty_p(tf)) {
422  /* algorithm: keep only memory write effects on variables with values */
423  FOREACH(EFFECT, e, el) {
424  action a = effect_action(e);
425  cell c = effect_cell(e);
427  entity v = reference_variable(r);
428 
429  if(store_effect_p(e)
430  && action_write_p(a)
431  && (!abstract_p || entity_abstract_location_p(v))
432  && !effects_package_entity_p(v)) {
433  // FI: this is not safe as the property can be changed without
434  // impact on pipsmake resource states
435  if(!get_bool_property("CONSTANT_PATH_EFFECTS")) {
436  // FI: too bad we are not sure the effects are constant
437  // FI: too bad we do not know which conversion function should be used
438  // simple_effect_to_constant_path_effects_with_pointer_values()
439  // simple_effect_to_constant_path_effects_with_points_to()
441  FOREACH(EFFECT, ce, cel)
442  tf = generic_apply_effect_to_transformer(tf, ce, apply_p, rhs, additional_p);
443  // gen_full_free_list(cel); ?
444  gen_free_list(cel);
445  }
446  else
447  tf = generic_apply_effect_to_transformer(tf, e, apply_p, rhs, additional_p);
448  }
449  }
450  }
451 
452  ifdebug(9) {
453  (void) print_transformer(tf);
454  pips_debug(9, "Ends\n");
455  }
456  return tf;
457 }
bool transformer_is_empty_p(transformer t)
Check that transformer t is the canonical representation of an empty transformer.
Definition: basic.c:172
list effect_to_constant_path_effects_with_no_pointer_information(effect)
bool store_effect_p(effect)
Definition: effects.c:1062
#define effect_cell(x)
Definition: effects.h:640
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
static transformer generic_apply_effect_to_transformer(transformer tf, effect e, bool apply_p, expression rhs, bool additional_p)

References action_write_p, cell_any_reference(), EFFECT, effect_action, effect_cell, effect_to_constant_path_effects_with_no_pointer_information(), effects_package_entity_p(), entity_abstract_location_p(), FOREACH, gen_free_list(), generic_apply_effect_to_transformer(), get_bool_property(), ifdebug, pips_debug, print_transformer, reference_variable, store_effect_p(), and transformer_is_empty_p().

Referenced by apply_abstract_effects_to_transformer(), apply_additional_effects_to_transformer(), and apply_effects_to_transformer().

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

◆ generic_complete_statement_transformer()

transformer generic_complete_statement_transformer ( transformer  t,
transformer  pre,
statement  s,
bool  identity_p 
)

Loops, do, for, while or repeat, have transformers linked to their body preconditions so as to compute those.

But the real loop transformer includes also the possible loop skip and the possible loop exit. This function completes transformer t, which is linked to the loop body precondition, and use additional information carried by statement s, analyzed with precondition pre to return the global loop transformer. If statement s is not a loop, a copy of t is returned.

Parameter identity_p is likely to be useless. It was added to track identity transformers before they were dealt with by transformer lists.

If i is a loop, the expected transformer can be more complex (see nga06) because the stores transformer is later used to compute the loop body precondition. It cannot take into account the exit condition. So the exit condition is added by the complete_xxx functions.

likely memory leak:-(. ct should be allocated in both test branches and freed at call site but I program everything under the opposite assumption

The refined transformer may be lost or stored as a block transformer is the loop is directly surrounded by a bloc or used to compute the transformer of the surroundings blokcs

No need to complete it

The search for an non identity execution path must be propagated downwards

Each component may or not update the state...

Parameters
prere
identity_pdentity_p

Definition at line 3706 of file ri_to_transformers.c.

3710 {
3711  /* If i is a loop, the expected transformer can be more complex (see
3712  nga06) because the stores transformer is later used to compute
3713  the loop body precondition. It cannot take into account the exit
3714  condition. So the exit condition is added by the complete_xxx
3715  functions. */
3718 
3719  if(instruction_loop_p(i)) {
3720  /* likely memory leak:-(. ct should be allocated in both test
3721  branches and freed at call site but I program everything under
3722  the opposite assumption */
3723  /* The refined transformer may be lost or stored as a block
3724  transformer is the loop is directly surrounded by a bloc or used to
3725  compute the transformer of the surroundings blokcs */
3727  }
3728  else if(instruction_whileloop_p(i)) {
3731  // This test could be deported by a call to
3732  // complete_whileloop_transformer()
3733  if(evaluation_before_p(e)) {
3734  ct = new_complete_whileloop_transformer(t, pre, w, !identity_p);
3735  }
3736  else {
3737  ct = complete_repeatloop_transformer(t, pre, w);
3738  }
3739  }
3740  else if(instruction_forloop_p(i)) {
3742  }
3743  else {
3744  if(identity_p) {
3745  /* No need to complete it */
3746  ct = copy_transformer(t);
3747  }
3748  else {
3749  /* The search for an non identity execution path must be propagated
3750  downwards */
3751  if(instruction_sequence_p(i)) {
3752  /* Each component may or not update the state... */
3753  }
3754  }
3755  }
3756  return ct;
3757 }
#define instruction_sequence_p(x)
Definition: ri.h:1512
#define instruction_loop_p(x)
Definition: ri.h:1518
#define instruction_loop(x)
Definition: ri.h:1520
#define whileloop_evaluation(x)
Definition: ri.h:3166
#define instruction_forloop_p(x)
Definition: ri.h:1536
#define instruction_forloop(x)
Definition: ri.h:1538
#define instruction_whileloop(x)
Definition: ri.h:1523
#define statement_instruction(x)
Definition: ri.h:2458
#define instruction_whileloop_p(x)
Definition: ri.h:1521
#define evaluation_before_p(x)
Definition: ri.h:1159
transformer complete_loop_transformer(transformer ltf, transformer pre, loop l)
The transformer computed and stored for a loop is useful to compute the loop body precondition,...
Definition: loop.c:1927
transformer complete_forloop_transformer(transformer t_body_star, transformer pre, forloop fl)
Definition: loop.c:1686
transformer new_complete_whileloop_transformer(transformer t_body_star, transformer pre, whileloop wl, bool entered_p)
entered_p is used to for the execution of at least one iteration
Definition: loop.c:1833
transformer complete_repeatloop_transformer(transformer t_body_star, transformer pre, whileloop wl)
Definition: loop.c:1910

References complete_forloop_transformer(), complete_loop_transformer(), complete_repeatloop_transformer(), copy_transformer(), evaluation_before_p, instruction_forloop, instruction_forloop_p, instruction_loop, instruction_loop_p, instruction_sequence_p, instruction_whileloop, instruction_whileloop_p, new_complete_whileloop_transformer(), statement_instruction, transformer_undefined, and whileloop_evaluation.

Referenced by complete_non_identity_statement_transformer(), and complete_statement_transformer().

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

◆ generic_substitute_formal_array_elements_in_transformer()

transformer generic_substitute_formal_array_elements_in_transformer ( transformer  tf,
entity  f,
list  pc,
transformer  pre,
list ef   __attribute__(unused),
bool  backward_p 
)

Early version.

Does not deal with varargs like any_user_call_site_to_transformer. Assume an equal number of formal and actual parameters.

Useful for transformers, backward means up the call tree.

Definition at line 1953 of file ri_to_transformers.c.

1954 {
1956  functional fft = type_functional(ft); // proper assert checked earlier
1957  list pl = functional_parameters(fft);
1958  // unsigned int pll = number_of_usable_functional_parameters(pl);
1959  list cpl = pl; // to simplify debugging
1960  int n = 1;
1961  int npl = (int) gen_length(pl);
1962  if(npl==1) {
1963  parameter p = PARAMETER(CAR(pl));
1964  if(type_void_p(parameter_type(p))) {
1965  pips_assert("No actual arguments",
1966  gen_length(pc)==0);
1967  }
1968  else {
1969  pips_assert("One actual argument",
1970  gen_length(pc)==1);
1971  }
1972  }
1973  else {
1974  pips_assert("Same number of actual and formal arguments",
1975  npl == (int) gen_length(pc));
1976  }
1977 
1979  if(!ENDP(all)) {
1981 
1982  FOREACH(EXPRESSION, e, pc) {
1983  entity fpv = find_ith_parameter(f, n); // formal parameter variable (and value)
1984  if(analyzed_entity_p(fpv)) {
1985  // FI: the filtering is only correct in backward mode
1986  if(!backward_p || gen_in_list_p(fpv, al)) {
1987  type fpt = compute_basic_concrete_type(parameter_type(PARAMETER(CAR(cpl)))); // formal parameter type
1988  type apt = compute_basic_concrete_type(expression_to_type(e)); // actual parameter type
1989 
1990  if(array_type_p(apt)
1991  && array_type_p(fpt)
1992  && get_bool_property("SEMANTICS_ANALYZE_CONSTANT_PATH")) {
1993  type et = array_type_to_element_type(fpt);
1994  if(analyzed_type_p(et) || struct_type_p(et))
1995  //tf = array_elements_substitution_in_transformer(tf, fpv, fpt, e, pre, NIL, backward_p);
1996  tf = new_array_elements_substitution_in_transformer(tf, fpv, fpt, e, pre, NIL, backward_p);
1997  // FI: what should we do when cft is undefined ?
1998  }
1999  }
2000  }
2001  n++;
2002  POP(cpl);
2003  }
2004  }
2005 
2006  return tf;
2007 }
bool gen_in_list_p(const void *vo, const list lx)
tell whether vo belongs to lx
Definition: list.c:734
bool array_type_p(type)
Definition: type.c:2942
type array_type_to_element_type(type)
returns the type of the elements of an array type, as a newly allocated type.
Definition: type.c:5700
transformer new_array_elements_substitution_in_transformer(transformer tf, entity fpv, type fpt __attribute__((unused)), expression e, transformer cpre __attribute__((unused)), list el __attribute__((unused)), bool backward_p)
list transformer_to_analyzed_arrays(transformer tf)
The list of array entities that appear in the basis of the transformer predicate as array element loc...
Definition: transformer.c:2793
list transformer_to_analyzed_array_locations(transformer tf)
Definition: transformer.c:2776
bool analyzed_entity_p(entity)
Definition: value.c:457

References analyzed_entity_p(), analyzed_type_p(), array_type_p(), array_type_to_element_type(), CAR, compute_basic_concrete_type(), ENDP, entity_basic_concrete_type(), EXPRESSION, expression_to_type(), f(), find_ith_parameter(), FOREACH, functional_parameters, gen_in_list_p(), gen_length(), get_bool_property(), int, new_array_elements_substitution_in_transformer(), NIL, PARAMETER, parameter_type, pips_assert, pl, POP, struct_type_p(), transformer_to_analyzed_array_locations(), transformer_to_analyzed_arrays(), type_functional, and type_void_p.

Referenced by substitute_formal_array_elements_in_precondition(), and substitute_formal_array_elements_in_transformer().

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

◆ generic_transformer_intra_to_inter()

transformer generic_transformer_intra_to_inter ( transformer  tf,
list  le,
bool  preserve_rv_p 
)

transformer translation from the module intraprocedural transformer to the module interprocedural transformer.

Values related to variables local to the module must be eliminated. Note that in C they should be eliminated earlier when the effect of the local declaration is taken into account or when the corresponding scope block is closed.

Filtered TransFormer ftf

cons * old_args = transformer_arguments(ftf);

get rid of tf's arguments that do not appear in effects le

build a list of arguments to suppress

FI: I do not understand anymore why corresponding old values do not have to be suppressed too (6 July 1993)

FI: because only read arguments are eliminated, non? (12 November 1995)

FI: the resulting intermediate transformer is not consistent (18 July 2003)

get rid of them

ftf = transformer_projection(ftf, lost_args);

free the temporary list of entities

get rid of local read variables

FI: why not use this loop to get rid of all local variables, read or written?

Variables with no impact on the caller world are eliminated. However, the return value associated to a function is conditionnally preserved.

get rid of them

free the temporary list of entities

Parameters
tff
lee
preserve_rv_preserve_rv_p

Definition at line 1398 of file ri_to_transformers.c.

1401 {
1402  cons * lost_args = NIL;
1403  /* Filtered TransFormer ftf */
1404  transformer ftf = transformer_dup(tf);
1405  /* cons * old_args = transformer_arguments(ftf); */
1406  Psysteme sc = SC_UNDEFINED;
1407  Pbase b = BASE_UNDEFINED;
1408  Pbase eb = BASE_UNDEFINED;
1409 
1410  pips_debug(8,"begin\n");
1411  pips_debug(8,"argument tf=%p\n",ftf);
1412  ifdebug(8) (void) dump_transformer(ftf);
1413 
1414  /* get rid of tf's arguments that do not appear in effects le */
1415 
1416  /* build a list of arguments to suppress */
1417  /* FI: I do not understand anymore why corresponding old values do not have
1418  * to be suppressed too (6 July 1993)
1419  *
1420  * FI: because only read arguments are eliminated, non? (12 November 1995)
1421  *
1422  * FI: the resulting intermediate transformer is not consistent (18 July 2003)
1423  */
1424  /*
1425  MAPL(ca,
1426  {entity e = ENTITY(CAR(ca));
1427  if(!effects_write_entity_p(le, e) &&
1428  !storage_return_p(entity_storage(e)))
1429  lost_args = arguments_add_entity(lost_args, e);
1430  },
1431  old_args);
1432  */
1433  /* get rid of them */
1434  /* ftf = transformer_projection(ftf, lost_args); */
1435 
1436  /* free the temporary list of entities */
1437  /*
1438  gen_free_list(lost_args);
1439  lost_args = NIL;
1440 
1441  pips_debug(8,"after first filtering ftf=%x\n",ftf);
1442  ifdebug(8) (void) dump_transformer(ftf);
1443  */
1444 
1445  /* get rid of local read variables */
1446 
1447  /* FI: why not use this loop to get rid of *all* local variables, read or written? */
1448 
1450  b = sc_base(sc);
1451  for(eb=b; !BASE_UNDEFINED_P(eb); eb = eb->succ) {
1452  entity e = (entity) vecteur_var(eb);
1453 
1454  if(e != (entity) TCST) {
1455  entity v = value_to_variable(e);
1456  /*
1457  entity v = entity_undefined;
1458 
1459  // Because static Fortran equivalences are indicated by an equality
1460  // Only one of the two equivalenced variables has values ?
1461  if(entity_has_values_p(v))
1462  v = value_to_variable(e);
1463  else
1464  v = e;
1465  */
1466 
1467  /* Variables with no impact on the caller world are eliminated.
1468  * However, the return value associated to a function is
1469  * conditionnally preserved.
1470  */
1471  if(!entity_constant_p(v)) {
1474  && (global_variable_p(v)||formal_parameter_p(v)))) {
1475  if(preserve_rv_p) {
1477  lost_args = arguments_add_entity(lost_args, e);
1478  }
1479  else {
1480  // get rid of non local return entities
1481  storage s = entity_storage(v);
1482  if(storage_return_p(s)) {
1483  entity f = storage_return(s);
1485  if(f!=m)
1486  lost_args = arguments_add_entity(lost_args, e);
1487  }
1488  else
1489  lost_args = arguments_add_entity(lost_args, e);
1490  }
1491  }
1492  }
1493  }
1494  }
1495  }
1496 
1497  /* get rid of them */
1498  ftf = transformer_projection(ftf, lost_args);
1499 
1500  /* free the temporary list of entities */
1501  gen_free_list(lost_args);
1502  lost_args = NIL;
1503 
1504  pips_debug(8,"return ftf=%p\n",ftf);
1505  ifdebug(8) (void) dump_transformer(ftf);
1506  pips_debug(8,"end\n");
1507 
1508  return ftf;
1509 }
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
bool concrete_effects_may_read_or_write_scalar_entity_p(list fx, entity e)
Definition: conflicts.c:1220
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
Definition: conflicts.c:1214
#define entity_constant_p(e)
bool global_variable_p(entity)
Is v a global variable such as "int i;".
Definition: variable.c:1510
bool formal_parameter_p(entity)
Definition: variable.c:1489
#define storage_return_p(x)
Definition: ri.h:2516
#define storage_return(x)
Definition: ri.h:2518
struct Svecteur * succ
Definition: vecteur-local.h:92
transformer transformer_projection(transformer t, list args)
values in args must be in t's base
Definition: transformer.c:1267
#define vecteur_var(v)
#define BASE_UNDEFINED_P(b)
#define BASE_UNDEFINED

References arguments_add_entity(), BASE_UNDEFINED, BASE_UNDEFINED_P, concrete_effects_may_read_or_write_scalar_entity_p(), dump_transformer, effects_may_read_or_write_scalar_entity_p(), entity_constant_p, entity_storage, f(), formal_parameter_p(), gen_free_list(), get_current_module_entity(), global_variable_p(), ifdebug, NIL, pips_debug, predicate_system, storage_return, storage_return_p, Svecteur::succ, TCST, transformer_dup(), transformer_projection(), transformer_relation, value_to_variable(), and vecteur_var.

Referenced by c_return_to_transformer(), and transformer_intra_to_inter().

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

◆ instruction_to_transformer()

static transformer instruction_to_transformer ( instruction  i,
transformer  pre,
list  e 
)
static

effects associated to instruction i

Definition at line 3599 of file ri_to_transformers.c.

3602 {
3604  test t;
3605  loop l;
3606  call c;
3607  whileloop wl;
3608  forloop fl;
3609 
3610  pips_debug(8,"begin\n");
3611 
3612  switch(instruction_tag(i)) {
3613  case is_instruction_block:
3615  break;
3616  case is_instruction_test:
3617  t = instruction_test(i);
3618  tf = test_to_transformer(t, pre, e);
3619  break;
3620  case is_instruction_loop:
3621  l = instruction_loop(i);
3622  tf = loop_to_transformer(l, pre, e);
3623  break;
3624  case is_instruction_whileloop: {
3625  wl = instruction_whileloop(i);
3626  tf = whileloop_to_transformer(wl, pre, e);
3627  break;
3628  }
3630  fl = instruction_forloop(i);
3631  tf = forloop_to_transformer(fl, pre, e);
3632  break;
3633  case is_instruction_goto:
3634  pips_internal_error("unexpected goto in semantics analysis");
3635  tf = transformer_identity();
3636  break;
3637  case is_instruction_call:
3638  c = instruction_call(i);
3639  tf = call_to_transformer(c, pre, e);
3640  break;
3643  break ;
3646  break;
3647  default:
3648  pips_internal_error("unexpected tag %d",
3649  instruction_tag(i));
3650  }
3651  pips_debug(9, "resultat:\n");
3652  ifdebug(9) (void) print_transformer(tf);
3653  pips_debug(8, "end\n");
3654  return tf;
3655 }
#define is_instruction_block
soft block->sequence transition
#define instruction_block(i)
@ is_instruction_goto
Definition: ri.h:1473
@ is_instruction_unstructured
Definition: ri.h:1475
@ is_instruction_whileloop
Definition: ri.h:1472
@ is_instruction_expression
Definition: ri.h:1478
@ is_instruction_test
Definition: ri.h:1470
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_forloop
Definition: ri.h:1477
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define instruction_expression(x)
Definition: ri.h:1541
#define instruction_call(x)
Definition: ri.h:1529
#define instruction_test(x)
Definition: ri.h:1517
#define instruction_unstructured(x)
Definition: ri.h:1532
static transformer test_to_transformer(test t, transformer pre, list ef)
effects of t
static transformer block_to_transformer(list b, transformer pre)
Recursive Descent in Data Structure Statement.
transformer call_to_transformer(call c, transformer pre, list ef)
Use to be static, but may be called from expressions in C.
transformer expression_to_transformer(expression exp, transformer pre, list el)
Just to capture side effects as the returned value is ignored.
Definition: expression.c:5190
transformer whileloop_to_transformer(whileloop l, transformer pre, list e)
effects of whileloop l
Definition: loop.c:2583
transformer forloop_to_transformer(forloop fl, transformer pre, list flel)
effects of forloop fl
Definition: loop.c:326
transformer loop_to_transformer(loop l, transformer pre, list e)
The transformer associated to a DO loop does not include the exit condition because it is used to com...
Definition: loop.c:1319
transformer unstructured_to_transformer(unstructured, transformer, list)
effects of u

References block_to_transformer(), call_to_transformer(), expression_to_transformer(), forloop_to_transformer(), ifdebug, instruction_block, instruction_call, instruction_expression, instruction_forloop, instruction_loop, instruction_tag, instruction_test, instruction_unstructured, instruction_whileloop, is_instruction_block, is_instruction_call, is_instruction_expression, is_instruction_forloop, is_instruction_goto, is_instruction_loop, is_instruction_test, is_instruction_unstructured, is_instruction_whileloop, loop_to_transformer(), pips_debug, pips_internal_error, print_transformer, test_to_transformer(), transformer_identity(), transformer_undefined, unstructured_to_transformer(), and whileloop_to_transformer().

Referenced by statement_to_transformer().

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

◆ integer_assign_to_transformer()

transformer integer_assign_to_transformer ( expression  lhs,
expression  rhs,
transformer  pre,
list  ef 
)

This function never returns an undefined transformer.

It is used for an assignment statement, not for an assignment operation. effects of assign

algorithm: if lhs and rhs are linear expressions on scalar integer variables, build the corresponding equation; else, use effects ef

should be extended to cope with constant integer division as in N2 = N/2 because it is used in real program; inequalities should be generated in that case 2*N2 <= N <= 2*N2+1

same remark for MOD operator

implementation: part of this function should be moved into transformer.c

&& integer_scalar_entity_p(e)

FI: the initial version was conservative because only affine scalar integer assignments were processed precisely. But non-affine operators and calls to user defined functions can also bring some information as soon as some integer read or write effect exists

check that all read effects are on integer scalar entities

Check that some read or write effects are on integer scalar entities. This is almost always true... Let's hope assigned_expression_to_transformer() returns quickly for array expressions used to initialize a scalar integer entity.

if some condition was not met and transformer derivation failed

Parameters
lhshs
rhshs
prere
eff

Definition at line 2693 of file ri_to_transformers.c.

2697 {
2698  /* algorithm: if lhs and rhs are linear expressions on scalar integer
2699  variables, build the corresponding equation; else, use effects ef
2700 
2701  should be extended to cope with constant integer division as in
2702  N2 = N/2
2703  because it is used in real program; inequalities should be
2704  generated in that case 2*N2 <= N <= 2*N2+1
2705 
2706  same remark for MOD operator
2707 
2708  implementation: part of this function should be moved into
2709  transformer.c
2710  */
2711 
2714 
2715  pips_debug(8,"begin\n");
2716 
2717  if(normalized_linear_p(n)) {
2718  Pvecteur vlhs = (Pvecteur) normalized_linear(n);
2719  entity e = (entity) vecteur_var(vlhs);
2720 
2721  if(entity_has_values_p(e) /* && integer_scalar_entity_p(e) */) {
2722  /* FI: the initial version was conservative because
2723  * only affine scalar integer assignments were processed
2724  * precisely. But non-affine operators and calls to user defined
2725  * functions can also bring some information as soon as
2726  * *some* integer read or write effect exists
2727  */
2728  /* check that *all* read effects are on integer scalar entities */
2729  /*
2730  if(integer_scalar_read_effects_p(ef)) {
2731  tf = assigned_expres`sion_to_transformer(e, rhs, ef);
2732  }
2733  */
2734  /* Check that *some* read or write effects are on integer
2735  * scalar entities. This is almost always true... Let's hope
2736  * assigned_expression_to_transformer() returns quickly for array
2737  * expressions used to initialize a scalar integer entity.
2738  */
2740  tf = assigned_expression_to_transformer(e, rhs, pre);
2741  }
2742  }
2743  }
2744  /* if some condition was not met and transformer derivation failed */
2745  if(tf==transformer_undefined)
2746  tf = effects_to_transformer(ef);
2747 
2748  pips_debug(6,"return tf=%lx\n", (unsigned long)tf);
2749  ifdebug(6) (void) print_transformer(tf);
2750  pips_debug(8,"end\n");
2751  return tf;
2752 }
bool some_integer_scalar_read_or_write_effects_p(cons *)
#define NORMALIZE_EXPRESSION(e)
#define normalized_linear_p(x)
Definition: ri.h:1779
#define normalized_linear(x)
Definition: ri.h:1781
transformer assigned_expression_to_transformer(entity v, expression expr, transformer pre)
transformer assigned_expression_to_transformer(entity e, expression expr, list ef): returns a transfo...
struct Svecteur * Pvecteur

References assigned_expression_to_transformer(), effects_to_transformer(), entity_has_values_p(), ifdebug, NORMALIZE_EXPRESSION, normalized_linear, normalized_linear_p, pips_debug, print_transformer, some_integer_scalar_read_or_write_effects_p(), transformer_undefined, and vecteur_var.

+ Here is the call graph for this function:

◆ intrinsic_to_transformer()

transformer intrinsic_to_transformer ( entity  e,
list  pc,
transformer  pre,
list  ef 
)

effects of intrinsic call

FI: this may happen, for instance with the macro definition of assert() or because the programmer writes "i>1? (i = 2): (i = 3);" instead of "i = i>1? 2 : 3;"

FI: the condition should be evaluated and considered true on exit, but this is sometimes captured by a macro definition and the code below is then useless

The result is positive and less than RAND_MAX, but it is ignored by the semantics anaysis

Parameters
pcc
prere
eff

Definition at line 911 of file ri_to_transformers.c.

915 {
917 
918  pips_debug(8, "begin\n");
919 
920  if(ENTITY_ASSIGN_P(e)) {
921  tf = any_assign_to_transformer(pc, ef, pre);
922  }
928  //tf = update_addition_operation_to_transformer(pc, ef, pre);
929  tf = any_update_to_transformer(e, pc, ef, pre);
930  }
933  tf = any_basic_update_to_transformer(e, pc, ef, pre);
934  }
935  else if(ENTITY_C_RETURN_P(e)) {
936  tf = c_return_to_transformer(e, pc, ef, pre);
937  }
940  tf = transformer_empty();
941  else if(ENTITY_COMMA_P(e)) {
942  tf = expressions_to_transformer(pc, pre);
943  }
944  else if(ENTITY_CONDITIONAL_P(e)) {
945  /* FI: this may happen, for instance with the macro definition of
946  assert() or because the programmer writes "i>1? (i = 2): (i =
947  3);" instead of "i = i>1? 2 : 3;" */
948  expression cond = EXPRESSION(CAR(pc));
949  expression e1 = EXPRESSION(CAR(CDR(pc)));
950  expression e2 = EXPRESSION(CAR(CDR(CDR(pc))));
951  tf = conditional_to_transformer(cond, e1, e2, pre, ef);
952  }
953  else if(ENTITY_ASSERT_SYSTEM_P(e)) {
954  /* FI: the condition should be evaluated and considered true on
955  exit, but this is sometimes captured by a macro definition and the code
956  below is then useless */
957  expression cond = EXPRESSION(CAR(pc));
958  tf = condition_to_transformer(cond, pre, true);
959  }
960  else if(ENTITY_RAND_P(e)) {
961  /* The result is positive and less than RAND_MAX, but it is
962  ignored by the semantics anaysis */
963  semantics_user_warning("Value returned by intrinsic \"rand\" is ignored.\n");
964  //tf = transformer_add_inequality_with_integer_constraint(transformer_identity(),
965  // e, 0, true);
966  tf = transformer_identity();
967  }
968  else
969  tf = effects_to_transformer(ef);
970 
971  pips_debug(8, "end\n");
972 
973  return tf;
974 }
transformer transformer_empty()
Allocate an empty transformer.
Definition: basic.c:120
#define ENTITY_PLUS_UPDATE_P(e)
#define ENTITY_MODULO_UPDATE_P(e)
#define ENTITY_STOP_P(e)
#define ENTITY_BITWISE_AND_UPDATE_P(e)
#define ENTITY_ASSIGN_P(e)
#define ENTITY_COMMA_P(e)
#define ENTITY_ASSERT_SYSTEM_P(e)
include <assert.h>
#define ENTITY_PRE_DECREMENT_P(e)
#define ENTITY_POST_DECREMENT_P(e)
#define ENTITY_EXIT_SYSTEM_P(e)
#define ENTITY_CONDITIONAL_P(e)
#define ENTITY_RIGHT_SHIFT_UPDATE_P(e)
#define ENTITY_BITWISE_OR_UPDATE_P(e)
#define ENTITY_RAND_P(e)
#define ENTITY_ABORT_SYSTEM_P(e)
#define ENTITY_MULTIPLY_UPDATE_P(e)
#define ENTITY_DIVIDE_UPDATE_P(e)
#define ENTITY_C_RETURN_P(e)
#define ENTITY_BITWISE_XOR_UPDATE_P(e)
#define ENTITY_MINUS_UPDATE_P(e)
#define ENTITY_LEFT_SHIFT_UPDATE_P(e)
#define ENTITY_ASSERT_FAIL_SYSTEM_P(e)
transformer any_basic_update_to_transformer(entity op, list args, list ef, transformer pre)
precondition
transformer any_assign_to_transformer(list args, list ef, transformer pre)
precondition
transformer any_update_to_transformer(entity op, list args, list ef, transformer pre)
precondition
transformer c_return_to_transformer(entity e __attribute__((__unused__)), list pc, list ef, transformer pre)
FI: This transformer carry the information about the value returned, but not the fact that the next s...
transformer expressions_to_transformer(list expl, transformer pre)
Compute the transformer associated to a list of expressions such as "i=0, j = 1;".
Definition: expression.c:5722
transformer conditional_to_transformer(expression cond, expression te, expression fe, transformer pre, list ef)
FI: not too smart to start with the special case with no value returned, just side-effects....
Definition: expression.c:5488
transformer condition_to_transformer(expression cond, transformer pre, bool veracity)
To capture side effects and to add C twist for numerical conditions.
Definition: expression.c:5348

References any_assign_to_transformer(), any_basic_update_to_transformer(), any_update_to_transformer(), c_return_to_transformer(), CAR, CDR, condition_to_transformer(), conditional_to_transformer(), effects_to_transformer(), ENTITY_ABORT_SYSTEM_P, ENTITY_ASSERT_FAIL_SYSTEM_P, ENTITY_ASSERT_SYSTEM_P, ENTITY_ASSIGN_P, ENTITY_BITWISE_AND_UPDATE_P, ENTITY_BITWISE_OR_UPDATE_P, ENTITY_BITWISE_XOR_UPDATE_P, ENTITY_C_RETURN_P, ENTITY_COMMA_P, ENTITY_CONDITIONAL_P, ENTITY_DIVIDE_UPDATE_P, ENTITY_EXIT_SYSTEM_P, ENTITY_LEFT_SHIFT_UPDATE_P, ENTITY_MINUS_UPDATE_P, ENTITY_MODULO_UPDATE_P, ENTITY_MULTIPLY_UPDATE_P, ENTITY_PLUS_UPDATE_P, ENTITY_POST_DECREMENT_P, ENTITY_POST_INCREMENT_P, ENTITY_PRE_DECREMENT_P, ENTITY_PRE_INCREMENT_P, ENTITY_RAND_P, ENTITY_RIGHT_SHIFT_UPDATE_P, ENTITY_STOP_P, EXPRESSION, expressions_to_transformer(), pips_debug, semantics_user_warning, transformer_empty(), transformer_identity(), and transformer_undefined.

Referenced by call_to_postcondition(), and call_to_transformer().

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

◆ new_array_element_backward_substitution_in_transformer()

transformer new_array_element_backward_substitution_in_transformer ( transformer  tf,
entity  l,
reference  fr,
reference  ar 
)

Substitute formal location entity l by a location entity corresponding to ar, if it is possible.

Parameters
tff
frr
arr

Definition at line 1723 of file ri_to_transformers.c.

1724 {
1725  reference nar = copy_reference(ar);
1727  reference_indices(nar) =
1728  gen_nconc(reference_indices(nar), nsl);
1730  if(entity_undefined_p(al)) {
1731  semantics_user_warning("Untranslatable reference \"%s\" because of"
1732  " imprecise effects.\n",
1733  reference_to_string(nar));
1734  list pl = CONS(ENTITY, l, NIL);
1735  tf = transformer_projection(tf, pl);
1736  gen_free_list(pl);
1737  }
1738  else {
1739  list pl = NIL;
1740  tf = substitute_scalar_stub_in_transformer(tf, l, al, true, &pl);
1741  if(ENDP(pl)) {
1742  ;
1743  }
1744  else {
1745  semantics_user_warning("Translation issues for location \"%s\"\n.",
1746  entity_user_name(l));
1747  tf = transformer_projection(tf, pl);
1748  gen_free_list(pl);
1749  }
1750  }
1751  free_reference(nar);
1752  return tf;
1753 }
reference copy_reference(reference p)
REFERENCE.
Definition: ri.c:2047

References CONS, constant_memory_access_path_to_location_entity(), copy_reference(), ENDP, ENTITY, entity_undefined_p, entity_user_name(), free_reference(), gen_free_list(), gen_full_copy_list(), gen_nconc(), NIL, pl, reference_indices, reference_to_string(), semantics_user_warning, substitute_scalar_stub_in_transformer(), and transformer_projection().

Referenced by new_array_elements_backward_substitution_in_transformer().

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

◆ new_array_elements_backward_substitution_in_transformer()

transformer new_array_elements_backward_substitution_in_transformer ( transformer  tf,
entity  fpv,
type fpt   __attribute__(unused),
expression  e,
transformer cpre   __attribute__(unused),
list el   __attribute__(unused) 
)

Definition at line 1755 of file ri_to_transformers.c.

1756 {
1758 
1759  FOREACH(ENTITY, l, ll) {
1760  value val = entity_initial(l);
1761  reference fr = value_reference(val); // Because of ll definition
1762  entity v = reference_variable(fr);
1763  if(v==fpv) {
1764  if(expression_reference_p(e)) {
1765  reference ar = expression_reference(e); // actual reference
1767  }
1768  else {
1769  // list cl = effects_lhs_expression_to_sources(e);
1771  int n = (int) gen_length(cl);
1772  transformer ntf = transformer_empty(); // True if there are no sources
1773  FOREACH(CELL, c, cl) {
1774  // No filtering on cells ?!? nowhere, null, anywhere ?
1775  reference ar = cell_any_reference(c);
1777  // Adjust the subscript list provided by the points-to
1778  // analysis, which is supposed to subscript all index
1779  // positions
1780  unsigned int d = array_type_dimension(fpt);
1781  list asl = reference_indices(ar), casl = list_undefined;
1782  int ns = (int) gen_length(asl);
1783  pips_assert("We except at least as many subscripts as dimenions",
1784  ns >= (int) d);
1785  int count = ns - d; // count is positive
1786  if(count==0) {
1787  // gen_free_list(asl); FI ?
1788  gen_full_free_list(asl);
1789  reference_indices(ar) = NIL;
1790  }
1791  else {
1792  list prev = list_undefined;
1793  for(casl = asl; !ENDP(casl) && count >0; POP(casl), count--) {
1794  prev = casl;
1795  }
1796  gen_full_free_list(CDR(casl));
1797  CDR(prev) = NIL;
1798  }
1799 
1800  transformer pntf = copy_transformer(tf);
1802  ntf = transformer_convex_hull(ntf, pntf);
1803  free_transformer(pntf);
1804  }
1805  }
1806  free_transformer(tf);
1807  tf = ntf;
1808  }
1809  }
1810  }
1811  return tf;
1812 }
static int count
Definition: SDG.c:519
void gen_full_free_list(list l)
Definition: genClib.c:1023
unsigned int array_type_dimension(type)
Definition: type.c:2947
transformer new_array_element_backward_substitution_in_transformer(transformer tf, entity l, reference fr, reference ar)
Substitute formal location entity l by a location entity corresponding to ar, if it is possible.

References array_type_dimension(), CDR, CELL, cell_any_reference(), copy_transformer(), count, ENDP, ENTITY, entity_initial, expression_reference(), expression_reference_p(), FOREACH, free_transformer(), gen_full_free_list(), gen_length(), int, list_undefined, new_array_element_backward_substitution_in_transformer(), NIL, pips_assert, POP, reference_indices, reference_variable, semantics_expression_to_points_to_sources(), semantics_usable_points_to_reference_p(), transformer_convex_hull(), transformer_empty(), transformer_to_analyzed_array_locations(), and value_reference.

Referenced by new_array_elements_substitution_in_transformer().

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

◆ new_array_elements_forward_substitution_in_transformer()

transformer new_array_elements_forward_substitution_in_transformer ( transformer  tf,
entity  fpv,
type fpt   __attribute__(unused),
expression  e,
transformer cpre   __attribute__(unused),
list el   __attribute__(unused) 
)

Definition at line 1875 of file ri_to_transformers.c.

1876 {
1877  // actual location list
1879 
1880  if(expression_reference_p(e)) {
1882  entity av = reference_variable(ar); // actual variable
1883  FOREACH(ENTITY, al, all) {
1884  value val = entity_initial(al); // actual location
1885  reference alr = value_reference(val); // Because of ll definition
1886  entity alv = reference_variable(alr); // Actual location variable
1887  if(alv==av) {
1888  tf = forward_substitute_array_location_in_transformer(tf, al, ar, alr, fpv);
1889  }
1890  }
1891  }
1892  else {
1894  int n = (int) gen_length(cl);
1895  transformer ntf = transformer_empty(); // True if there are no sources
1896  FOREACH(CELL, c, cl) {
1897  // No filtering on cells ?!? nowhere, null, anywhere ?
1899  entity av = reference_variable(ar);
1901  // Adapt actual reference by remove the last fd array indices
1902  list arsl = reference_indices(ar);
1903  int arsn = (int) gen_length(arsl);
1904  int fd = (int) array_type_dimension(fpt);
1905  pips_assert("The points-to references include all subscripts",
1906  arsn>=fd);
1907  int count = arsn-fd;
1908  if(count>=1) {
1909  while(count>1) {
1910  count --;
1911  POP(arsl);
1912  }
1913  CDR(arsl) = NIL;
1914  }
1915 
1916  transformer ptf = copy_transformer(tf);
1917  FOREACH(ENTITY, al, all) {
1918  value val = entity_initial(al); // actual location
1919  reference alr = value_reference(val); // Because of ll definition
1920  entity alv = reference_variable(alr); // Actual location variable
1921  if(alv==av) {
1922  ptf = forward_substitute_array_location_in_transformer(ptf, al, ar, alr, fpv);
1923  }
1924  }
1925  ntf = transformer_convex_hull(ntf, ptf);
1926  free_transformer(ptf);
1927  }
1928  free_reference(ar);
1929  }
1930  free_transformer(tf);
1931  tf = ntf;
1932  // pips_internal_error("Not implemented yet.\n");
1933  }
1934 
1935  return tf;
1936 }
static transformer forward_substitute_array_location_in_transformer(transformer tf, entity al, reference ar, reference alr, entity fpv)
Compute the subscript list suffix in the abstract location reference alr with respect to the actual r...

References array_type_dimension(), CDR, CELL, cell_any_reference(), copy_reference(), copy_transformer(), count, ENTITY, entity_initial, expression_reference(), expression_reference_p(), FOREACH, forward_substitute_array_location_in_transformer(), free_reference(), free_transformer(), gen_length(), int, NIL, pips_assert, POP, reference_indices, reference_variable, semantics_expression_to_points_to_sources(), semantics_usable_points_to_reference_p(), transformer_convex_hull(), transformer_empty(), transformer_to_analyzed_array_locations(), and value_reference.

Referenced by new_array_elements_substitution_in_transformer().

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

◆ new_array_elements_substitution_in_transformer()

transformer new_array_elements_substitution_in_transformer ( transformer  tf,
entity  fpv,
type fpt   __attribute__(unused),
expression  e,
transformer cpre   __attribute__(unused),
list el   __attribute__(unused),
bool  backward_p 
)

Definition at line 1938 of file ri_to_transformers.c.

1939 {
1940  if(backward_p)
1941  tf = new_array_elements_backward_substitution_in_transformer(tf, fpv, fpt, e, cpre, el);
1942  else
1943  tf = new_array_elements_forward_substitution_in_transformer(tf, fpv, fpt, e, cpre, el);
1944  return tf;
1945 }
transformer new_array_elements_forward_substitution_in_transformer(transformer tf, entity fpv, type fpt __attribute__((unused)), expression e, transformer cpre __attribute__((unused)), list el __attribute__((unused)))
transformer new_array_elements_backward_substitution_in_transformer(transformer tf, entity fpv, type fpt __attribute__((unused)), expression e, transformer cpre __attribute__((unused)), list el __attribute__((unused)))

References new_array_elements_backward_substitution_in_transformer(), and new_array_elements_forward_substitution_in_transformer().

Referenced by generic_substitute_formal_array_elements_in_transformer().

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

◆ number_of_usable_functional_parameters()

unsigned int number_of_usable_functional_parameters ( list  pl)

Number of formal parameters in pl before a vararg is reached.

The varargs are not analyzed.

Parameters
pll

Definition at line 1518 of file ri_to_transformers.c.

1519 {
1520  int n = 0;
1521  bool void_p = false;
1522  FOREACH(PARAMETER, p, pl) {
1523  type lpt = ultimate_type(parameter_type(p));
1524  if(type_void_p(lpt))
1525  void_p = true;
1526  else if(type_varargs_p(lpt))
1527  break;
1528  else
1529  n++;
1530  }
1531  if(void_p && n!=0)
1532  pips_internal_error("Inconsistent internal representation: \"void\" type used among several formal parameters.\n");
1533  return n;
1534 }

References FOREACH, PARAMETER, parameter_type, pips_internal_error, pl, type_varargs_p, type_void_p, and ultimate_type().

Referenced by any_user_call_site_to_transformer().

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

◆ perform_array_element_substitutions_in_transformer()

static void perform_array_element_substitutions_in_transformer ( transformer  tf,
reference  ar,
reference  fr,
list  dl,
transformer prec   __attribute__(unused),
bool  backward_p 
)
static

Recursive function to substitute formal and actual array elements referenced or partially referenced by ar and fr.

The precondition should be used if VLA

can we build ar==fr as an equation, i.e. substitute fr by ar

Definition at line 1583 of file ri_to_transformers.c.

1584 {
1585  if(ENDP(dl)) {
1587  if(analyzed_type_p(art)) {
1588  /* can we build ar==fr as an equation, i.e. substitute fr by ar */
1591  if(!entity_undefined_p(av) && !entity_undefined_p(fv)) {
1592  // Let's assume the new value is the variable
1593  if(backward_p)
1594  transformer_value_substitute(tf, fv, av);
1595  else
1596  transformer_value_substitute(tf, av, fv);
1597  entity oav = entity_to_old_value(av);
1598  if(!entity_undefined_p(oav)) {
1600  if(!entity_undefined_p(ofv)) {
1601  if(backward_p)
1602  transformer_value_substitute(tf, ofv, oav);
1603  else
1604  transformer_value_substitute(tf, oav, ofv);
1605  }
1606  }
1607  }
1608  }
1609  else if(struct_type_p(art)) {
1610  if(array_type_p(art)) {
1611  variable v = type_variable(art);
1612  list ndl = variable_dimensions(v);
1613  pips_assert("", !ENDP(ndl));
1614  perform_array_element_substitutions_in_transformer(tf, ar, fr, ndl, prec, backward_p);
1615  }
1616  else {
1617  list fl = struct_type_to_fields(art);
1618  FOREACH(ENTITY, f, fl) {
1620  if(analyzed_type_p(ft) || struct_type_p(ft) || array_type_p(ft)) {
1621  reference nar = copy_reference(ar);
1622  reference nfr = copy_reference(fr);
1624  CONS(EXPRESSION,
1626  NIL));
1628  CONS(EXPRESSION,
1630  NIL));
1631  perform_array_element_substitutions_in_transformer(tf, nar, nfr, NIL, prec, backward_p);
1632  free_reference(nar);
1633  free_reference(nfr);
1634  }
1635  }
1636  }
1637  }
1638  else if(array_type_p(art)) {
1639  type et = array_type_to_element_type(art);
1640  if(analyzed_type_p(et) || struct_type_p(et)) {
1641  variable v = type_variable(art);
1642  list ndl = variable_dimensions(v);
1643  pips_assert("", !ENDP(ndl));
1644  perform_array_element_substitutions_in_transformer(tf, ar, fr, ndl, prec, backward_p);
1645  ;
1646  }
1647  }
1648  }
1649  else {
1650  // FI: we add the subscripts one by one, which makes the types
1651  // hard to interpret when a multidimensional array is indexed I
1652  // think it's better to stop the attempt much earlier according to
1653  // the formal parameter type.
1654 #if false
1656  type et = type_undefined;
1657  if(array_type_p(et))
1658  et = array_type_to_element_type(art);
1659  else if(pointer_type_p(art))
1660  et = type_to_pointed_type(art);
1661  else
1663  if(analyzed_type_p(et) || struct_type_p(et)) {
1664 #endif
1665  // FI: not the correct selection
1666  dimension d = DIMENSION(CAR(dl));
1667  expression up = dimension_upper(d);
1668  int c, i;
1670  for(i = 0; i <= c; i++) {
1671  // FI: could be done without extensive copies and free
1672  expression s = int_to_expression(i); // new subscript
1673  reference nar = copy_reference(ar);
1674  reference nfr = copy_reference(fr);
1676  CONS(EXPRESSION, s, NIL));
1679  perform_array_element_substitutions_in_transformer(tf, nar, nfr, CDR(dl), prec, backward_p);
1680  free_reference(nar);
1681  free_reference(nfr);
1682  }
1683  }
1684  else {
1685  entity fv = reference_variable(fr);
1686  entity av = reference_variable(ar);
1687  pips_user_warning("Formal parameter \"%s\" linked to VLA \"%s\""
1688  " with upper bound \"%s\": Not implemented yet.\n",
1689  entity_user_name(fv),
1690  entity_user_name(av),
1691  expression_to_string(up));
1692  }
1693 #if false
1694  }
1695  else
1696  pips_internal_error("Wrong filtering.\n");
1697 #endif
1698  }
1699 }
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
bool extended_integer_constant_expression_p_to_int(expression e, int *result)
Definition: expression.c:874
type type_to_pointed_type(type)
returns t if t is not a pointer type, and the pointed type if t is a pointer type.
Definition: type.c:5265
bool pointer_type_p(type)
Check for scalar pointers.
Definition: type.c:2993
list struct_type_to_fields(type)
Definition: type.c:5798
#define type_undefined
Definition: ri.h:2883

References analyzed_type_p(), array_type_p(), array_type_to_element_type(), CAR, CDR, CONS, constant_memory_access_path_to_location_entity(), copy_expression(), copy_reference(), DIMENSION, dimension_upper, ENDP, ENTITY, entity_basic_concrete_type(), entity_to_expression(), entity_to_old_value(), entity_undefined_p, entity_user_name(), EXPRESSION, expression_to_string(), extended_integer_constant_expression_p_to_int(), external_entity_to_old_value(), f(), FOREACH, free_reference(), gen_nconc(), int_to_expression(), NIL, pips_assert, pips_internal_error, pips_user_warning, pointer_type_p(), points_to_reference_to_concrete_type(), reference_indices, reference_variable, struct_type_p(), struct_type_to_fields(), transformer_value_substitute(), type_to_pointed_type(), type_undefined, type_variable, and variable_dimensions.

Referenced by array_elements_substitution_in_transformer().

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

◆ safe_assigned_expression_to_transformer()

transformer safe_assigned_expression_to_transformer ( entity  v,
expression  expr,
transformer  pre 
)

Always returns a fully defined transformer.

FI: The property to compute transformers in context is not taken into account to add information from pre within tf. pre is used to evaluate expr, but is not made part of tf.

Side effects in expression ?

Parameters
exprxpr
prere

Definition at line 2651 of file ri_to_transformers.c.

2654 {
2656 
2657  if(expression_undefined_p(expr)) {
2658  ; // That is fixed below
2659  }
2660  else
2661  tf = assigned_expression_to_transformer(v, expr, pre);
2662 
2663  if(transformer_undefined_p(tf)) {
2664  if(get_bool_property("SEMANTICS_COMPUTE_TRANSFORMERS_IN_CONTEXT"))
2665  tf = transformer_range(pre);
2666  else
2667  tf = transformer_identity();
2668 
2669  /* Side effects in expression ? */
2671  tf = transformer_combine(tf, setf);
2672  free_transformer(setf);
2673 
2674  // FI: need to investigate interplay between typedef and
2675  // qualifier?
2676  // FI: Issue: a static variable qualified with const and accessed thru
2677  // a function. See hs_list_smoothing() in hyantes
2678  // Or you see the issue as using assignment analysis for static definition...
2681  }
2682  }
2683 
2684  pips_assert("tf is defined", !transformer_undefined_p(tf));
2685  pips_assert("tf is consistent", transformer_consistency_p(tf));
2686 
2687  return tf;
2688 }
transformer transformer_add_modified_variable_entity(transformer tf, entity var)
FI: like the previous function, but supposed to end up with a consistent transformer.
Definition: basic.c:909
bool type_with_const_qualifier_p(type)
Is there a const qualifier associated to type t.
Definition: type.c:5483
transformer expression_effects_to_transformer(expression expr)
Definition: expression.c:3465

References assigned_expression_to_transformer(), entity_has_values_p(), entity_type, expression_effects_to_transformer(), expression_undefined_p, free_transformer(), get_bool_property(), pips_assert, transformer_add_modified_variable_entity(), transformer_combine(), transformer_consistency_p(), transformer_identity(), transformer_range(), transformer_undefined, transformer_undefined_p, and type_with_const_qualifier_p().

Referenced by declaration_to_transformer(), and declaration_to_transformer_list().

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

◆ statement_to_transformer()

transformer statement_to_transformer ( statement  s,
transformer  spre 
)

stmt precondition

old transformer for s

new transformer for s under spre

nt updated with loop exit information

Transformation REFINE_TRANSFORMERS is being executed: add information available from the statement precondition

it would be nicer to control warning_on_redefinition

FI: OK, we will have to switch to the new declaration representation some day, but the old representation is still fine.

not very smart because declarations_to_transformer() computes post and free it...

add type information

FI: how do we want to handle declarations:

int i = 1; => T() {i==1}

or

int i = 1; => T(i) {i==1}

What is the impact of this choice? BC prefers the second one because it it consistent for convex effect computation.

Note: this issue could be dealt with earlier in declarations_to_transformer()

FI: the code below might be useful again when declarations are carried by any kind of statement

Option 1

Option 2, currently bugged

Currently, the preconditions is useless as only the effects will be used to compute the CONTINUE transformer.

Remove information cancelled by abstract effects

This correction should be moved down in test_to_transformer(), loop_to_transformer() and call_to_transformer() to reduce its impact. See Ticket 792.

add array references information using proper effects

nt = transformer_normalize(nt, 0);

add type information

nt = transformer_normalize(nt, 0);

When we leave a block the local stack allocated variables disappear

Get rid of the dynamic and stack variables declared in this block statement. No stack variable should be analyzed as the stack area is used only for dependent types.

nt = transformer_normalize(nt, 7);

nt = transformer_normalize(nt, 4);

(void) print_transformer(load_statement_transformer(s));

When the statement is virtually replicated via control nodes, the statement transformer is the convex hull of all its replicate transformers.

This implies that transformers are computed in context and that we are dealing with a non-deterministic unstructured with several nodes for a unique statement.

Written abstract locations may require some information destruction

The current implementation is too crude. A new function is needed, abstract_effects_to_transformer(). The current implementation is OK for anywhere effects.

Also, abstract effects should not be applied several times. For instance, a block statement cannot add new effects that have not already been taken into account. A test or a loop only add abstract effects linked to the condition or the loop control. Which leaves us mostly with call statements. Which means that abstract effects should be taken into account at a lower level.

This is mathematically correct but very inefficient (see ticket 644) and useless as long anymodule:anywhere is the only abstract effect we have to deal with.

Not a sufficient solution: free_transformer(t); t = etf;

store or update the statement transformer

delete_statement_transformer(s);

store_statement_transformer(s, t);

The transformer returned for the statement is not always the transformer stored for the statement. This happens for loops and for context sensitive transformers for replicated statements in CFG/unstructured. See comments in loop.c

Parameters
sprepre

Definition at line 3759 of file ri_to_transformers.c.

3762 {
3764  list e = NIL;
3766  transformer ot = transformer_undefined; /* old transformer for s */
3767  transformer nt = transformer_undefined; /* new transformer for s under spre */
3768  transformer te = transformer_undefined; /* nt updated with loop exit information */
3770 
3771  pips_debug(8,"begin for statement %03td (%td,%td) with precondition %p:\n",
3774  ifdebug(8) {
3775  pips_assert("The statement and its substatements are fully defined",
3777  (void) print_transformer(spre);
3778  }
3779 
3780  pips_assert("spre is a consistent precondition",
3781  transformer_consistent_p(spre));
3782 
3785 
3786  if(get_bool_property("SEMANTICS_COMPUTE_TRANSFORMERS_IN_CONTEXT")) {
3788  transformer_range(spre); // FI: transformer_range() implies
3789  // projection(s) and a possibly strong
3790  // increase of the number of
3791  // constraints. Many constraints may be
3792  // redundant as far as integer points
3793  // are concerned, but not redundant for
3794  // rational numbers. We could use an
3795  // approximate projection, elimination
3796  // of all constraints containing an old value...
3797  if(refine_transformers_p) {
3798  /* Transformation REFINE_TRANSFORMERS is being executed: add
3799  information available from the statement precondition */
3801  transformer srpre_r = transformer_range(srpre);
3802 
3803  pre = transformer_domain_intersection(pre, srpre_r);
3804  pre = transformer_normalize(pre, 2); // FI: redundancy
3805  // elimination required
3806  free_transformer(srpre_r);
3807  }
3808  }
3809  else {
3810  // Avoid lots of test in the callees ot statement_to_transformer
3811  // pre = transformer_undefined;
3812  pre = transformer_identity();
3813  }
3814 
3815  pips_assert("pre is a consistent precondition",
3817 
3818  pips_debug(8,"Range precondition pre:\n");
3819  ifdebug(8) {
3820  (void) print_transformer(pre);
3821  }
3822 
3825 
3826  /* it would be nicer to control warning_on_redefinition */
3827  if (transformer_undefined_p(ot)
3828  || get_bool_property("SEMANTICS_COMPUTE_TRANSFORMERS_IN_CONTEXT")) {
3829  //list dl = declaration_statement_p(s) ? statement_declarations(s) : NIL;
3831 
3832  /* FI: OK, we will have to switch to the new declaration
3833  representation some day, but the old representation is still
3834  fine.*/
3836  && !declaration_statement_p(s)) {
3837  // FI: Just to gain some time before dealing with controlizer and declarations updates
3838  //pips_internal_error("Statement %p carries declarations");
3839  semantics_user_warning("Statement %d (%p) carries declarations\n",
3840  statement_number(s), s);
3841  }
3842 
3843  if(!ENDP(dl)) {
3845  /* not very smart because declarations_to_transformer() computes post and free it...*/
3846  transformer post = transformer_apply(dt, pre);
3847  transformer ipre = transformer_range(post);
3849 
3850  // FI: this should not be duplicated. Temporary fix for modulo07.c
3851  /* add type information */
3852  /*
3853  if(get_bool_property("SEMANTICS_USE_TYPE_INFORMATION")) {
3854  transformer_add_type_information(nt);
3855  }
3856  */
3857 
3858  ifdebug(8) {
3859  pips_debug(8, "Statement local preconditions due to declarations:");
3860  print_transformer(ipre);
3861  }
3862 
3863  /* FI: how do we want to handle declarations:
3864  *
3865  * int i = 1; => T() {i==1}
3866  *
3867  * or
3868  *
3869  * int i = 1; => T(i) {i==1}
3870  *
3871  * What is the impact of this choice? BC prefers the second one
3872  * because it it consistent for convex effect computation.
3873  *
3874  * Note: this issue could be dealt with earlier in
3875  * declarations_to_transformer()
3876  */
3877  /* FI: the code below might be useful again when declarations
3878  are carried by any kind of statement */
3879  //it = instruction_to_transformer(i, ipre, e);
3880  //nt = transformer_combine(dt, it);
3881  //free_transformer(it);
3882  if(false) {
3883  /* Option 1 */
3884  nt = dt;
3885  }
3886  else if(false) {
3887  /* Option 2, currently bugged */
3888  /* Currently, the preconditions is useless as only the
3889  effects will be used to compute the CONTINUE transformer. */
3890  it = instruction_to_transformer(i, pre, e);
3891  nt = transformer_image_intersection(it, dt);
3892  free_transformer(it);
3893  free_transformer(dt);
3894  }
3895  else {
3896  nt = dt; // Do nothing because everything has been taken care of by
3897  // declaration_to_transformer()
3898  }
3899  free_transformer(post);
3900  // free_transformer(ipre);
3901  }
3902  else {
3903  nt = instruction_to_transformer(i, pre, e);
3904  }
3905 
3906  /* Remove information cancelled by abstract effects */
3907  /* This correction should be moved down in test_to_transformer(),
3908  loop_to_transformer() and call_to_transformer() to reduce its
3909  impact. See Ticket 792. */
3912  }
3913 
3914  /* add array references information using proper effects */
3915  if(get_bool_property("SEMANTICS_TRUST_ARRAY_REFERENCES")) {
3917  /* nt = transformer_normalize(nt, 0); */
3918  }
3919 
3920  /* add type information */
3921  if(get_bool_property("SEMANTICS_USE_TYPE_INFORMATION")
3922  || get_bool_property("SEMANTICS_USE_TYPE_INFORMATION_IN_TRANSFORMERS")) {
3924  /* nt = transformer_normalize(nt, 0); */
3925  }
3926 
3927  /* When we leave a block the local stack allocated variables
3928  disappear */
3929  if(statement_block_p(s) && !ENDP(dl=statement_declarations(s))) {
3930  /* Get rid of the dynamic and stack variables declared in this block
3931  statement. No stack variable should be analyzed as the stack
3932  area is used only for dependent types. */
3933  bool location_p = get_bool_property("SEMANTICS_ANALYZE_CONSTANT_PATH");
3934  if(location_p) {
3935  // This is a general case that should always work
3936  // The complexity is controlled by the length of the transformer basis
3937  list vl = transformer_to_local_values(nt, dl);
3938  if(!ENDP(vl))
3939  nt = safe_transformer_projection(nt, vl);
3940  }
3941  else { // The complexity is controlled by the length of dl
3943  if(!ENDP(vl))
3944  nt = safe_transformer_projection(nt, vl);
3945  }
3946  }
3947  /* nt = transformer_normalize(nt, 7); */
3948  /* nt = transformer_normalize(nt, 4); */
3949  nt = transformer_normalize(nt, 2);
3950 
3951  if(!transformer_consistency_p(nt)) {
3952  _int so = statement_ordering(s);
3953  (void) fprintf(stderr, "statement %03td (%td,%td):\n",
3954  statement_number(s),
3956  /* (void) print_transformer(load_statement_transformer(s)); */
3957  (void) print_transformer(nt);
3958  dump_transformer(nt);
3959  pips_internal_error("Inconsistent transformer detected");
3960  }
3961  ifdebug(1) {
3962  pips_assert("Transformer is internally consistent",
3964  }
3965 
3966  /* When the statement is virtually replicated via control nodes, the
3967  statement transformer is the convex hull of all its replicate
3968  transformers. */
3969  if(transformer_undefined_p(ot)) {
3970  if (get_int_property("SEMANTICS_NORMALIZATION_LEVEL_BEFORE_STORAGE") == 4)
3971  nt = transformer_normalize(nt, 4);
3972  t = copy_transformer(nt);
3973  }
3974  else {
3975  /* This implies that transformers are computed in context and that
3976  we are dealing with a non-deterministic unstructured with several
3977  nodes for a unique statement. */
3978  t = transformer_convex_hull(nt, ot);
3979 
3980  ifdebug(1) {
3981  pips_assert("transformers are computed in context",
3982  get_bool_property("SEMANTICS_COMPUTE_TRANSFORMERS_IN_CONTEXT"));
3983  pips_debug(1, "Convex hull for transformer of statement %03td (%td,%td)\n",
3986  pips_debug(1, "Previous transformer:\n");
3987  (void) print_transformer(ot);
3988  pips_debug(1, "New transformer:\n");
3989  (void) print_transformer(nt);
3990  pips_debug(1, "Resulting transformer:\n");
3991  (void) print_transformer(t);
3992  }
3993  }
3994 
3995  /* Written abstract locations may require some information destruction
3996  *
3997  * The current implementation is too crude. A new function is
3998  * needed, abstract_effects_to_transformer(). The current
3999  * implementation is OK for anywhere effects.
4000  *
4001  * Also, abstract effects should not be applied several times. For
4002  * instance, a block statement cannot add new effects that have not
4003  * already been taken into account. A test or a loop only add
4004  * abstract effects linked to the condition or the loop
4005  * control. Which leaves us mostly with call statements. Which means
4006  * that abstract effects should be taken into account at a lower
4007  * level.
4008  */
4009 
4010  //if(effects_abstract_location_p(e) && !statement_block_p(s)) {
4011  // FI: it would be better to use directly
4012  // apply_effects_to_transformer() and maybe legal to use
4013  // apply_additional_effects_to_transformer(). FI: it might be
4014  // safer to define apply_abstract_effects_to_transformer() as
4015  // suggested above.
4016  //transformer etf = effects_to_transformer(e);
4017  /* This is mathematically correct but very inefficient (see ticket
4018  644) and useless as long *anymodule*:*anywhere* is the only
4019  abstract effect we have to deal with.
4020  */
4021  //t = transformer_combine(t, etf);
4022  //nt = transformer_combine(nt, etf);
4023  //free_transformer(etf);
4024  //t = apply_abstract_effects_to_transformer(t, e);
4025  //nt = apply_abstract_effects_to_transformer(nt, e);
4026  /* Not a sufficient solution:
4027  free_transformer(t);
4028  t = etf;
4029  */
4030  //}
4031 
4032  /* store or update the statement transformer */
4033  if(transformer_undefined_p(ot)) {
4035  }
4036  else {
4037  transformer_free(ot);
4039  /* delete_statement_transformer(s); */
4040  /* store_statement_transformer(s, t); */
4041  }
4042  }
4043  else {
4044  semantics_user_warning("redefinition for statement %03d (%d,%d)\n",
4047  pips_internal_error("transformer redefinition");
4048  }
4049 
4050  ifdebug(1) {
4051  _int so = statement_ordering(s);
4053 
4054  (void) fprintf(stderr, "statement %03td (%td,%td), transformer %p:\n",
4055  statement_number(s),
4057  stf);
4058  (void) print_transformer(stf);
4059  pips_assert("same pointer", stf==t);
4060  }
4061 
4062  /* The transformer returned for the statement is not always the
4063  transformer stored for the statement. This happens for loops and for
4064  context sensitive transformers for replicated statements in
4065  CFG/unstructured. See comments in loop.c */
4066 
4067  te = complete_statement_transformer(nt, pre, s);
4068 
4069  free_transformer(pre);
4070 
4071  ifdebug(8) {
4072  pips_assert("The statement and its substatements are still fully defined",
4074  }
4075 
4076  pips_debug(8,"end for statement %03td (%td,%td) with t=%p, nt=%p and te=%p\n",
4078  ORDERING_STATEMENT(statement_ordering(s)), t, nt, te);
4079 
4081  (void) pop_statement_global_stack();
4082 
4083  return te;
4084 }
int get_int_property(const string)
bool transformer_consistent_p(transformer p)
Definition: ri.c:2622
void transformer_free(transformer t)
Definition: basic.c:68
bool transformer_internal_consistency_p(transformer t)
Same as above but equivalenced variables should not appear in the argument list or in the predicate b...
Definition: basic.c:790
bool refine_transformers_p
Transformer recomputation cannot be of real use unless an interprocedural analysis is performed.
list load_cumulated_rw_effects_list(statement)
bool effects_abstract_location_p(list)
Returns true if at least one effect of effect list el is related to an abstract location.
Definition: effects.c:288
bool all_statements_defined_p(statement)
Definition: statement.c:3213
bool declaration_statement_p(statement)
Had to be optimized according to Beatrice Creusillet.
Definition: statement.c:224
intptr_t _int
_INT
Definition: newgen_types.h:53
#define ORDERING_NUMBER(o)
#define ORDERING_STATEMENT(o)
#define statement_block_p(stat)
statement pop_statement_global_stack(void)
Definition: static.c:352
void push_statement_on_statement_global_stack(statement)
Definition: static.c:333
#define statement_ordering(x)
Definition: ri.h:2454
#define statement_declarations(x)
Definition: ri.h:2460
#define statement_number(x)
Definition: ri.h:2452
void transformer_add_reference_information(transformer tf, statement s)
static transformer instruction_to_transformer(instruction i, transformer pre, list e)
effects associated to instruction i
transformer complete_statement_transformer(transformer t, transformer pre, statement s)
Returns the effective transformer ct for a given statement s.
static transformer apply_abstract_effects_to_transformer(transformer tf, list el)
transformer declarations_to_transformer(list dl, transformer pre)
For C declarations.
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
list dynamic_variables_to_values(list list_mod)
Build the list of values to be projected when the declaration list list_mod is no longer valid becaus...
Definition: mappings.c:1007
void transformer_add_type_information(transformer)
type.c
Definition: type.c:162
transformer load_statement_precondition(statement)
void store_statement_transformer(statement, transformer)
transformer load_statement_transformer(statement)
void update_statement_transformer(statement, transformer)
transformer transformer_image_intersection(transformer t1, transformer t2)
allocate a new transformer based on transformer t1 and postcondition t2
Definition: transformer.c:608
list transformer_to_local_values(transformer tf, list dl)
Build a list of values appearing in tf that are linked to a variable in dl.
Definition: transformer.c:2821
transformer safe_transformer_projection(transformer t, list args)
t may be undefined, args may contain values unrelated to t
Definition: transformer.c:1187
transformer transformer_domain_intersection(transformer tf, transformer pre)
Restrict the domain of the relation tf with pre.
Definition: transformer.c:661

References all_statements_defined_p(), apply_abstract_effects_to_transformer(), complete_statement_transformer(), copy_transformer(), declaration_statement_p(), declarations_to_transformer(), dump_transformer, dynamic_variables_to_values(), effects_abstract_location_p(), ENDP, fprintf(), free_transformer(), get_bool_property(), get_int_property(), ifdebug, instruction_to_transformer(), load_cumulated_rw_effects_list(), load_statement_precondition(), load_statement_transformer(), NIL, ORDERING_NUMBER, ORDERING_STATEMENT, pips_assert, pips_debug, pips_internal_error, pop_statement_global_stack(), print_transformer, push_statement_on_statement_global_stack(), refine_transformers_p, safe_transformer_projection(), semantics_user_warning, statement_block_p, statement_declarations, statement_global_stack_defined_p(), statement_instruction, statement_number, statement_ordering, stf(), store_statement_transformer(), transformer_add_reference_information(), transformer_add_type_information(), transformer_apply(), transformer_consistency_p(), transformer_consistent_p(), transformer_convex_hull(), transformer_domain_intersection(), transformer_free(), transformer_identity(), transformer_image_intersection(), transformer_internal_consistency_p(), transformer_normalize(), transformer_range(), transformer_to_local_values(), transformer_undefined, transformer_undefined_p, and update_statement_transformer().

Referenced by any_loop_to_k_transformer(), block_to_transformer(), dag_or_cycle_to_flow_sensitive_postconditions_or_transformers(), generic_module_name_to_transformers(), loop_to_transformer(), process_ready_node(), process_unreachable_node(), standard_whileloop_to_transformer(), test_to_transformer(), test_to_transformer_list(), unreachable_node_to_transformer(), and unstructured_to_transformers().

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

◆ struct_reference_assignment_or_equality_to_transformer()

static transformer struct_reference_assignment_or_equality_to_transformer ( reference  r,
type  t,
expression  rhs,
transformer  pre,
list ef   __attribute__(unused),
bool  assign_p 
)
static
Parameters
rreference to a struct
ttype of v, which much be matched by rhs expression type and which must not contain any named type
rhsright-hand side expression
eflist of effects
preprecondition of the assignment
Returns
a transformer that must be defined as some field assignments may be analyzable whereas others just generate side-effects

capture side effects in rhs expression, e.g. "s = sa[i++];"

Check type. Should be useless as the parser should have generated a consistent statement...

Get the list of potential right-hand side structs

And loop over them

A very similar loop is used in lhs_expression_to_transformer...

Free list ll or free list ll and its content

In case return values of a callee appear, project them.

FI: It should be applied only to callees' return values when this function is called for s = f()... and not even when it is called for the call site g(as) with g(fs) where as is an actual struct and fs a formal struct.

The projection must be performed by the caller, which knows what kind of projection, if any, is needed.

Definition at line 2997 of file ri_to_transformers.c.

2998 {
2999  /* capture side effects in rhs expression, e.g. "s = sa[i++];" */
3000  // struct are not recognized as analyzable type; use an integer type
3001  // as tmp will not be used by the transformer?
3002  //transformer tf = safe_any_expression_side_effects_to_transformer(rhs, pre, true);
3003 
3005 
3006  /* Check type. Should be useless as the parser should have generated
3007  * a consistent statement...
3008  */
3009  type rhs_t = expression_to_type(rhs);
3010  type c_rhs_t = compute_basic_concrete_type(rhs_t);
3011  pips_assert("Both types are equal", type_equal_p(t, c_rhs_t));
3012 
3013  /* Get the list of potential right-hand side structs */
3015  int n = (int) gen_length(ll);
3016 
3017  /* And loop over them
3018  *
3019  * A very similar loop is used in lhs_expression_to_transformer...
3020  */
3022  FOREACH(CELL, cp, ll) {
3023  reference rhsl = cell_any_reference(cp); // rhs location
3024  // The preconditions may make the convex hull useful when
3025  // different locations have known values or are
3026  // constrained...
3027  transformer rt = copy_transformer(pre);
3028 
3029  if(semantics_usable_points_to_reference_p(rhsl, rhs, n)) {
3030  if(assign_p)
3031  rt = transformer_apply_field_assignments(rt, r, rhsl, t);
3032  else
3033  rt = transformer_apply_field_equalities(rt, r, rhsl, t);
3034  }
3035  else {
3036  if(assign_p)
3038  else
3040  }
3041 
3042  // FI: is it useful to handle different cases and then to lose
3043  // most of the information most of the time with a convex
3044  // hull?
3045  if (transformer_undefined_p(ntf))
3046  ntf = rt;
3047  else {
3048  ntf = transformer_convex_hull(ntf, rt);
3049  free_transformer(rt);
3050  }
3051  }
3052 
3053  /* Free list ll or free list ll and its content */
3054  gen_free_list(ll);
3055 
3056  if(!transformer_undefined_p(ntf)) {
3057  tf = transformer_combine(tf, ntf);
3058  free_transformer(ntf);
3059  }
3060 
3061  /* In case return values of a callee appear, project them.
3062  *
3063  * FI: It should be applied only to callees' return values when this
3064  * function is called for s = f()... and not even when it is called
3065  * for the call site g(as) with g(fs) where as is an actual struct
3066  * and fs a formal struct.
3067  *
3068  * The projection must be performed by the caller, which knows what
3069  * kind of projection, if any, is needed.
3070  */
3071  // tf = generic_transformer_intra_to_inter(tf, ef, false);
3074 
3075  return tf;
3076 }
transformer transformer_apply_field_equalities(transformer t, reference l, reference r, type st)
transformer transformer_apply_unknown_field_equalities(transformer t, reference l, type st)
transformer transformer_apply_unknown_field_assignments(transformer t, reference l, type st)
transformer transformer_apply_field_assignments(transformer t, reference l, reference r, type st)
transformer transformer_return_value_projection(entity f, transformer t)
Project return values that are not linked to function f.
Definition: transformer.c:1220

References CELL, cell_any_reference(), compute_basic_concrete_type(), copy_transformer(), cp, expression_to_type(), FOREACH, free_transformer(), gen_free_list(), gen_length(), get_current_module_entity(), int, pips_assert, safe_expression_to_transformer(), semantics_expression_to_points_to_sources(), semantics_usable_points_to_reference_p(), transformer_apply_field_assignments(), transformer_apply_field_equalities(), transformer_apply_unknown_field_assignments(), transformer_apply_unknown_field_equalities(), transformer_combine(), transformer_convex_hull(), transformer_return_value_projection(), transformer_undefined, transformer_undefined_p, and type_equal_p().

Referenced by struct_reference_assignment_to_transformer(), and struct_reference_equality_to_transformer().

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

◆ struct_reference_assignment_to_transformer()

transformer struct_reference_assignment_to_transformer ( reference  r,
type  t,
expression  rhs,
transformer  pre,
list  ef 
)
Parameters
rhshs
prere
eff

Definition at line 3078 of file ri_to_transformers.c.

3079 {
3080  return struct_reference_assignment_or_equality_to_transformer(r, t, rhs, pre, ef, true);
3081 }
static transformer struct_reference_assignment_or_equality_to_transformer(reference r, type t, expression rhs, transformer pre, list ef __attribute__((unused)), bool assign_p)

References struct_reference_assignment_or_equality_to_transformer().

Referenced by assign_rhs_to_reflhs_to_transformer(), and struct_variable_assignment_to_transformer().

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

◆ struct_reference_equality_to_transformer()

transformer struct_reference_equality_to_transformer ( reference  r,
type  t,
expression  rhs,
transformer  pre,
list  ef 
)
Parameters
rhshs
prere
eff

Definition at line 3083 of file ri_to_transformers.c.

3084 {
3085  return struct_reference_assignment_or_equality_to_transformer(r, t, rhs, pre, ef, false);
3086 }

References struct_reference_assignment_or_equality_to_transformer().

Referenced by struct_variable_equality_to_transformer().

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

◆ struct_variable_assignment_to_transformer()

transformer struct_variable_assignment_to_transformer ( entity  v,
type  t,
expression  rhs,
transformer  pre,
list  ef 
)
Parameters
vassigned struct variable (does not handle the general case, "e1==e2;" where e1 and e2 are lhs expressions
ttype of v, which much be matched by rhs expression type and which must not contain any named type
rhsright-hand side expression
eflist of effects
preprecondition of the assignment
Returns
a transformer that must be defined as some field assignments may be analyzable whereas others just generate side-effects
Parameters
rhshs
prere
eff

Definition at line 3100 of file ri_to_transformers.c.

3101 {
3102  reference r = make_reference(v, NIL);
3104  free_reference(r);
3105  return tf;
3106 }

References free_reference(), make_reference(), NIL, and struct_reference_assignment_to_transformer().

Referenced by assign_rhs_to_reflhs_to_transformer(), and c_return_to_transformer().

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

◆ struct_variable_equality_to_transformer()

transformer struct_variable_equality_to_transformer ( entity  v,
type  t,
expression  rhs,
transformer  pre,
list  ef 
)
Parameters
rhshs
prere
eff

Definition at line 3108 of file ri_to_transformers.c.

3109 {
3110  reference r = make_reference(v, NIL);
3111  transformer tf = struct_reference_equality_to_transformer(r, t, rhs, pre, ef);
3112  free_reference(r);
3113  return tf;
3114 }
transformer struct_reference_equality_to_transformer(reference r, type t, expression rhs, transformer pre, list ef)

References free_reference(), make_reference(), NIL, and struct_reference_equality_to_transformer().

Referenced by any_user_call_site_to_transformer().

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

◆ substitute_formal_array_elements_in_precondition()

transformer substitute_formal_array_elements_in_precondition ( transformer  tf,
entity  f,
list  pc,
transformer  pre,
list  ef 
)
Parameters
tff
pcc
prere
eff

Definition at line 2014 of file ri_to_transformers.c.

2015 {
2016  return generic_substitute_formal_array_elements_in_transformer(tf, f, pc, pre, ef, false);
2017 }
transformer generic_substitute_formal_array_elements_in_transformer(transformer tf, entity f, list pc, transformer pre, list ef __attribute__((unused)), bool backward_p)
Early version.

References f(), and generic_substitute_formal_array_elements_in_transformer().

Referenced by process_call_for_summary_precondition().

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

◆ substitute_formal_array_elements_in_transformer()

transformer substitute_formal_array_elements_in_transformer ( transformer  tf,
entity  f,
list  pc,
transformer  pre,
list  ef 
)
Parameters
tff
pcc
prere
eff

Definition at line 2009 of file ri_to_transformers.c.

2010 {
2011  return generic_substitute_formal_array_elements_in_transformer(tf, f, pc, pre, ef, true);
2012 }

References f(), and generic_substitute_formal_array_elements_in_transformer().

Referenced by c_user_call_to_transformer().

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

◆ test_to_transformer()

static transformer test_to_transformer ( test  t,
transformer  pre,
list  ef 
)
static

effects of t

EXPRESSION_TO_TRANSFORMER() SHOULD BE USED MORE EFFECTIVELY

Ideally, they should be initialized with the current best precondition, intraprocedural if nothing else better is available. This function's profile as well as most function profiles in ri_to_transformers should be modifed.

True condition transformer

False condition transformer

tftwc = precondition_add_condition_information(tftwc, e, context, true);

tffwc = precondition_add_condition_information(tffwc, e, context, false);

Definition at line 817 of file ri_to_transformers.c.

820 {
821  statement st = test_true(t);
822  statement sf = test_false(t);
823  transformer tf;
824 
825  /* EXPRESSION_TO_TRANSFORMER() SHOULD BE USED MORE EFFECTIVELY */
826 
827  pips_debug(8,"begin\n");
828 
830  expression e = test_condition(t);
831  /* Ideally, they should be initialized with the current best
832  precondition, intraprocedural if nothing else better is
833  available. This function's profile as well as most function
834  profiles in ri_to_transformers should be modifed. */
839  transformer tffwc = transformer_dup(tftwc);
840  transformer post_tftwc = transformer_undefined;
841  transformer post_tffwc = transformer_undefined;
842  list ta = NIL;
843  list fa = NIL;
844  /* True condition transformer */
846  /* False condition transformer */
848 
849  /*
850  tftwc = transformer_dup(statement_to_transformer(st));
851  tffwc = transformer_dup(statement_to_transformer(sf));
852  */
853 
854 
855  /* tftwc = precondition_add_condition_information(tftwc, e, context, true); */
856  tftwc = transformer_apply(tct, context);
857  ifdebug(8) {
858  pips_debug(8, "tftwc before transformer_temporary_value_projection %p:\n", tftwc);
859  (void) print_transformer(tftwc);
860  }
863  ifdebug(8) {
864  pips_debug(8, "tftwc before transformer_apply %p:\n", tftwc);
865  (void) print_transformer(tftwc);
866  }
867  post_tftwc = transformer_apply(statement_to_transformer(st, tftwc), tftwc);
868  //post_tftwc = transformer_normalize(post_tftwc, 2);
869 
870  ifdebug(8) {
871  pips_debug(8, "tftwc after transformer_apply %p:\n", tftwc);
872  (void) print_transformer(tftwc);
873  pips_debug(8, "post_tftwc after transformer_apply %p:\n", post_tftwc);
874  (void) print_transformer(post_tftwc);
875  }
876 
877  /* tffwc = precondition_add_condition_information(tffwc, e, context, false); */
878  tffwc = transformer_apply(fct, context);
881  post_tffwc = transformer_apply(statement_to_transformer(sf, tffwc), tffwc);
882  //post_tffwc = transformer_normalize(post_tffwc, 2);
883 
884  ifdebug(8) {
885  pips_debug(8, "post_tftwc before transformer_convex_hull %p:\n", post_tftwc);
886  (void) print_transformer(post_tftwc);
887  pips_debug(8, "post_tffwc after transformer_apply %p:\n", post_tffwc);
888  (void) print_transformer(post_tffwc);
889  }
890  tf = transformer_convex_hull(post_tftwc, post_tffwc);
892  transformer_free(tftwc);
893  transformer_free(tffwc);
894  transformer_free(post_tftwc);
895  transformer_free(post_tffwc);
896  free_arguments(ta);
897  free_arguments(fa);
898  }
899  else {
901  (void) statement_to_transformer(st, id);
902  (void) statement_to_transformer(sf, id);
903  tf = effects_to_transformer(ef);
904  free_transformer(id);
905  }
906 
907  pips_debug(8,"end\n");
908  return tf;
909 }
transformer precondition_to_abstract_store(transformer pre)
Get rid of all old values and arguments.
Definition: basic.c:871
#define pips_flag_p(p)
for upwards compatibility with Francois's modified version
#define SEMANTICS_FLOW_SENSITIVE
#define test_false(x)
Definition: ri.h:2837
#define test_true(x)
Definition: ri.h:2835
#define test_condition(x)
Definition: ri.h:2833
Definition: delay.c:253

References condition_to_transformer(), effects_to_transformer(), free_arguments(), free_transformer(), ifdebug, NIL, pips_debug, pips_flag_p, precondition_to_abstract_store(), print_transformer, reset_temporary_value_counter(), SEMANTICS_FLOW_SENSITIVE, statement_to_transformer(), test_condition, test_false, test_true, transformer_apply(), transformer_convex_hull(), transformer_dup(), transformer_free(), transformer_identity(), transformer_temporary_value_projection(), transformer_undefined, and transformer_undefined_p.

Referenced by instruction_to_transformer().

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

◆ transformer_apply_field_assignments()

transformer transformer_apply_field_assignments ( transformer  t,
reference  l,
reference  r,
type  st 
)
Parameters
stt

Definition at line 2925 of file ri_to_transformers.c.

2926 {
2927  return transformer_apply_field_assignments_or_equalities(t, l, r, st, true);
2928 }
transformer transformer_apply_field_assignments_or_equalities(transformer t, reference l, reference r, type st, bool assign_p)
For all analyzable fields f, apply the assignment "le.f = re.f;" to transformer t.

References transformer_apply_field_assignments_or_equalities().

Referenced by struct_reference_assignment_or_equality_to_transformer(), and transformer_apply_field_assignments_or_equalities().

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

◆ transformer_apply_field_assignments_or_equalities()

transformer transformer_apply_field_assignments_or_equalities ( transformer  t,
reference  l,
reference  r,
type  st,
bool  assign_p 
)

For all analyzable fields f, apply the assignment "le.f = re.f;" to transformer t.

If s1.f is a struct, go down recursively.

It is assumed that s1 and s2 have the exact same concrete struct type, st.

Transformer t is updated. It is assumed to contain the current precondition.

Parameters
stt
assign_pssign_p

Definition at line 2876 of file ri_to_transformers.c.

2877 {
2878  list fl = struct_type_to_fields(st);
2879  FOREACH(ENTITY, f, fl) {
2881  if(analyzed_type_p(ft)) {
2888 
2889  if(!entity_undefined_p(l1)) {
2891  // The value of location l1 is changed
2892  if(assign_p)
2893  tf = transformer_add_modified_variable(tf, l1);
2894  if(!entity_undefined_p(l2)) {
2895  // both locations are analyzed
2896  tf = transformer_add_equality(tf, l1, l2);
2897  }
2898  t = transformer_combine(t, tf);
2899  free_transformer(tf);
2900  }
2901  else {
2902  pips_internal_error("Not implemented yet.\n");
2903  }
2904  free_reference(r1);
2905  free_reference(r2); // another option would be to remove the last subscript
2906  }
2907  else if(type_struct_p(ft)) {
2908  // This piece of code could be integrate in the previous
2909  // alternative to share most of its code
2915  // GO down recursively
2916  tf = transformer_apply_field_assignments(tf, l1, r1, ft);
2917  if(!transformer_undefined_p(tf))
2918  t = transformer_combine(t, tf);
2920  }
2921  }
2922  return t;
2923 }
transformer transformer_add_equality(transformer tf, entity v1, entity v2)
Add an equality between two values (two variables?)
Definition: basic.c:436
reference add_subscript_to_reference(reference r, expression s)
Add a last subscript expression s to a reference r.
Definition: expression.c:224
#define type_struct_p(x)
Definition: ri.h:2962

References add_subscript_to_reference(), analyzed_type_p(), constant_memory_access_path_to_location_entity(), copy_reference(), ENTITY, entity_basic_concrete_type(), entity_to_expression(), entity_undefined_p, f(), FOREACH, free_reference(), free_transformer(), pips_internal_error, struct_type_to_fields(), transformer_add_equality(), transformer_add_modified_variable(), transformer_apply_field_assignments(), transformer_combine(), transformer_identity(), transformer_undefined_p, and type_struct_p.

Referenced by transformer_apply_field_assignments(), and transformer_apply_field_equalities().

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

◆ transformer_apply_field_equalities()

transformer transformer_apply_field_equalities ( transformer  t,
reference  l,
reference  r,
type  st 
)
Parameters
stt

Definition at line 2930 of file ri_to_transformers.c.

2931 {
2932  return transformer_apply_field_assignments_or_equalities(t, l, r, st, false);
2933 }

References transformer_apply_field_assignments_or_equalities().

Referenced by struct_reference_assignment_or_equality_to_transformer().

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

◆ transformer_apply_unknown_field_assignments()

transformer transformer_apply_unknown_field_assignments ( transformer  t,
reference  l,
type  st 
)
Parameters
stt

Definition at line 2976 of file ri_to_transformers.c.

2977 {
2979 }
static transformer transformer_apply_unknown_field_assignments_or_equalities(transformer t, reference l, type st, bool assign_p)
Simplified version of transformer_apply_field_assignments() with an unknown rhs.

References transformer_apply_unknown_field_assignments_or_equalities().

Referenced by struct_reference_assignment_or_equality_to_transformer().

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

◆ transformer_apply_unknown_field_assignments_or_equalities()

static transformer transformer_apply_unknown_field_assignments_or_equalities ( transformer  t,
reference  l,
type  st,
bool  assign_p 
)
static

Simplified version of transformer_apply_field_assignments() with an unknown rhs.

Definition at line 2938 of file ri_to_transformers.c.

2939 {
2940  list fl = struct_type_to_fields(st);
2941  FOREACH(ENTITY, f, fl) {
2946 
2947  if(!entity_undefined_p(l1)) {
2948  tf = transformer_identity();
2949  // The value of location l1 is changed
2950  if(assign_p)
2951  tf = transformer_add_modified_variable(tf, l1);
2952  }
2953  else {
2954  // r1 may reference a substruct [or an array element?] and
2955  // you may need to go down recursively
2957  if(struct_type_p(ft)) {
2958  tf = transformer_identity();
2959  // The value of location l1 is changed
2961  }
2962  else {
2963  // Do nothing
2964  ;
2965  }
2966  }
2967  free_reference(r1);
2968  if(!transformer_undefined_p(tf)) {
2969  t = transformer_combine(t, tf);
2970  free_transformer(tf);
2971  }
2972  }
2973  return t;
2974 }

References add_subscript_to_reference(), constant_memory_access_path_to_location_entity(), copy_reference(), ENTITY, entity_basic_concrete_type(), entity_to_expression(), entity_undefined_p, f(), FOREACH, free_reference(), free_transformer(), struct_type_p(), struct_type_to_fields(), transformer_add_modified_variable(), transformer_combine(), transformer_identity(), transformer_undefined, and transformer_undefined_p.

Referenced by transformer_apply_unknown_field_assignments(), and transformer_apply_unknown_field_equalities().

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

◆ transformer_apply_unknown_field_equalities()

transformer transformer_apply_unknown_field_equalities ( transformer  t,
reference  l,
type  st 
)
Parameters
stt

Definition at line 2981 of file ri_to_transformers.c.

2982 {
2984 }

References transformer_apply_unknown_field_assignments_or_equalities().

Referenced by struct_reference_assignment_or_equality_to_transformer().

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

◆ transformer_filter_subsumed_variables()

static transformer transformer_filter_subsumed_variables ( transformer  tf)
static

The transformer returned for a call site may be too accurate for the caller.

Information about specific variables available at the callee level may be lost at the caller level because some abstract locations wraps up together independent variables. For instance, as soon as any_module:any_where appears, information loss seems inevitable.

So, values in tf related to variables with no values in the current module must be projected, except for the values of the return variable and for the constants used to represent floating point numbers and strings.

This should be moved down to library transformer or vecteur using value_entity_p() as an argument, up to typing issues...

Clean up argument

Definition at line 988 of file ri_to_transformers.c.

989 {
991  Pbase b = sc_base(sc);
992  Pbase cb = b;
993  list svl = NIL; // subsumed value list
994  list pvl = NIL; // preserved variable list
996  entity orv = entity_undefined; // should be useless in C, but is not
997  // in Fortran: unification
998 
999  /* This should be moved down to library transformer or vecteur using
1000  value_entity_p() as an argument, up to typing issues... */
1001 
1002  for(cb = b; !BASE_NULLE_P(cb); cb = vecteur_succ(cb)) {
1003  entity v = (entity) vecteur_var(cb);
1004  if(variable_return_p(v)) {
1005  string orvn = strdup(concatenate(entity_name(v),
1007  NULL));
1008  rv = v;
1009  orv = gen_find_tabulated(orvn, entity_domain);
1010  free(orvn);
1011  }
1012  }
1013 
1014  for(cb = b; !BASE_NULLE_P(cb); cb = vecteur_succ(cb)) {
1015  entity v = (entity) vecteur_var(cb);
1016  if(!value_entity_p(v) && v!=rv && v!=orv && !entity_constant_p(v) && !entity_symbolic_p(v)) {
1017  semantics_user_warning("Value \"%s\" is projected because of "
1018  "imprecise effects\n", entity_name(v));
1019  svl = CONS(ENTITY, v, svl);
1020  }
1021  }
1022 
1023  tf = transformer_projection(tf, svl);
1024 
1025  gen_free_list(svl);
1026 
1027  /* Clean up argument */
1028  FOREACH(ENTITY, var, transformer_arguments(tf)) {
1029  if(entity_has_values_p(var))
1030  pvl = CONS(ENTITY, var, pvl);
1031  }
1032 
1033  pvl = gen_nreverse(pvl);
1035  transformer_arguments(tf) = pvl;
1036 
1037  return tf;
1038 }
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
void * gen_find_tabulated(const char *, int)
Definition: tabulated.c:218
#define entity_symbolic_p(e)
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
#define entity_domain
newgen_syntax_domain_defined
Definition: ri.h:410
char * strdup()
#define OLD_VALUE_SUFFIX
bool value_entity_p(entity)
Definition: value.c:976
#define vecteur_succ(v)
#define BASE_NULLE_P(b)

References BASE_NULLE_P, concatenate(), CONS, ENTITY, entity_constant_p, entity_domain, entity_has_values_p(), entity_name, entity_symbolic_p, entity_undefined, FOREACH, free(), gen_find_tabulated(), gen_free_list(), gen_nreverse(), NIL, OLD_VALUE_SUFFIX, predicate_system, semantics_user_warning, strdup(), transformer_arguments, transformer_projection(), transformer_relation, value_entity_p(), variable_return_p(), vecteur_succ, and vecteur_var.

Referenced by c_user_call_to_transformer(), and call_to_transformer().

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

◆ transformer_formal_parameter_projection()

transformer transformer_formal_parameter_projection ( entity  f,
transformer  t 
)

Dealing with an interprocedural transformer, weak consistency is not true

pips_assert("t is weakly consistent", transformer_weak_consistency_p(t));

Definition at line 1537 of file ri_to_transformers.c.

1538 {
1540  Pbase b = sc_base(sc);
1541  Pbase cd = BASE_UNDEFINED;
1542  list fpl = NIL;
1543 
1544  /* Dealing with an interprocedural transformer, weak consistency is
1545  not true */
1546  /* pips_assert("t is weakly consistent",
1547  transformer_weak_consistency_p(t));*/
1548  pips_assert("sc is consistent", sc_weak_consistent_p(sc));
1549  pips_assert("t is weakly consistent", transformer_weak_consistency_p(t));
1550 
1551  for(cd = b; !BASE_NULLE_P(cd); cd = vecteur_succ(cd)) {
1552  entity val = (entity) vecteur_var(cd);
1553  entity var = value_to_variable(val);
1554  if(!location_entity_p(var)) {
1555  storage s = entity_storage(var);
1556 
1558  fpl = CONS(ENTITY, var, fpl);
1559  }
1560  }
1561 
1562  ifdebug(1) {
1563  pips_debug(1, "Transformer before projection:\n");
1564  dump_transformer(t);
1565  pips_debug(1, "Projected variables:\n");
1566  print_entities(fpl);
1567  fprintf(stderr, "\n");
1568  }
1569 
1570  t = transformer_projection(t, fpl);
1571 
1572  gen_free_list(fpl);
1573 
1574  return t;
1575 }
bool location_entity_p(entity)
Definition: locations.c:349
void print_entities(list l)
Definition: entity.c:167
#define storage_formal_p(x)
Definition: ri.h:2522
#define formal_function(x)
Definition: ri.h:1406
bool sc_weak_consistent_p(Psysteme sc)
check that sc is well defined, that the numbers of equalities and inequalities are consistent with th...
Definition: sc.c:362

References BASE_NULLE_P, BASE_UNDEFINED, CONS, dump_transformer, ENTITY, entity_storage, f(), formal_function, fprintf(), gen_free_list(), ifdebug, location_entity_p(), NIL, pips_assert, pips_debug, predicate_system, print_entities(), sc_weak_consistent_p(), storage_formal, storage_formal_p, transformer_projection(), transformer_relation, transformer_weak_consistency_p(), value_to_variable(), vecteur_succ, and vecteur_var.

Referenced by c_user_call_to_transformer().

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

◆ transformer_intra_to_inter()

transformer transformer_intra_to_inter ( transformer  tf,
list  le 
)
Parameters
tff
lee

Definition at line 1510 of file ri_to_transformers.c.

1512 {
1513  return generic_transformer_intra_to_inter(tf, le, true);
1514 }

References generic_transformer_intra_to_inter().

Referenced by generic_module_name_to_transformers(), module_name_to_total_preconditions(), and program_precondition().

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

◆ update_cp_with_rhs_to_transformer()

static transformer update_cp_with_rhs_to_transformer ( reference __attribute__((unused))  cp,
expression __attribute__((unused))  rhs,
transformer __attribute__((unused))  pre,
list __attribute__((unused))  ef 
)
static

see assign_rhs_to_cp_to_transformer and update_reflhs_with_rhs_to_transformer to make update_cp_with_rhs_to_transformer

Parameters
cpconstant path to be assign (the caller need to verify that cp is really a constant path)
rhsexpression to assign
preprecondition
efeffects of assign
Returns
transformer_undefined or transformer with the assign

Definition at line 3321 of file ri_to_transformers.c.

3326 {
3329  if(!entity_undefined_p(l)) {
3330  type t = entity_type(l);
3332  tf = safe_any_expression_to_transformer(tmp, rhs, pre, true);
3333  entity nv = entity_to_new_value(l);
3334  entity ov = entity_to_old_value(l);
3336  transformer_arguments(tf) =
3339  }
3340  return tf;
3341 }
transformer transformer_add_3d_affine_constraint(transformer tf, int a1, entity v1, int a2, entity v2, int a3, entity v3, int cst, bool equation_p)
Add the constraint a1 v1 + a2 v2 + a3 v3 + cst <= or == 0.
Definition: basic.c:536

References arguments_add_entity(), constant_memory_access_path_to_location_entity(), cp, entity_to_new_value(), entity_to_old_value(), entity_type, entity_undefined_p, make_local_temporary_value_entity(), safe_any_expression_to_transformer(), transformer_add_3d_affine_constraint(), transformer_arguments, transformer_temporary_value_projection(), transformer_undefined, VALUE_MONE, VALUE_ONE, and VALUE_ZERO.

Referenced by update_reflhs_with_rhs_to_transformer().

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

◆ update_reflhs_with_rhs_to_transformer()

static transformer update_reflhs_with_rhs_to_transformer ( entity  op,
reference  rlhs,
expression  rhs,
transformer  pre,
list  ef 
)
static
Parameters
opupdate operator
rlhsreference to update
rhsexpression to assign
preprecondition
efeffects of assign
Returns
transformer_undefined or transformer with the update

Definition at line 3351 of file ri_to_transformers.c.

3357 {
3359 
3360  if(ENDP(reference_indices(rlhs))) {
3361  entity v = reference_variable(rlhs);
3364  expression n_rhs = MakeBinaryCall(sop, ve, copy_expression(rhs));
3365 
3366  tf = any_scalar_assign_to_transformer(v, n_rhs, ef, pre);
3367  free_expression(n_rhs);
3368  }
3369  else if (constant_path_analyzed_p()) { // see assign_rhs_to_reflhs_to_transformer
3370  // Check if the reference rlhs is a constant path or not
3371  // TODO : can_be_constant_path_p(rlhs) return true when the ref is a constant path
3372  // * !effect_reference_dereferencing_p(rlhs, &exact_p) -> is too permissive
3373  // can return true when it's not a constant path like a[i]
3374  // can make a side effect for the declaration of variable in parameter (only?), don't know why
3375  // for instance with Semantics-New/Pointer.sub/memcopy01
3376  // void memcopy01([...], char dst[size]) --> void memcopy01([...], char dst[i])
3377  // without this side effect !effect_reference_dereferencing_p seem to be better than store_independent_reference_p
3378  // * store_independent_reference_p(rlhs) -> is too too much restrictive
3379  // can return false for some cp like a[0], can't permit to treat the array
3380  // return false for the structure too
3381  // it can't permit to treat anything interesting
3382  if (can_be_constant_path_p(rlhs)) {
3383  pips_user_warning("update_cp_with_rhs_to_transformer not done yet\n");
3384  // see assign_rhs_to_cp_to_transformer to make update_cp_with_rhs_to_transformer
3385  tf = update_cp_with_rhs_to_transformer(rlhs, rhs, pre, ef);
3386  }
3387  else {
3388  // TODO : reference_to_constant_path(ref)
3389  // function that convert any reference in a constant path
3390  // expression_to_points_to_sources() isn't good, doesn't work for some array for the moment
3391  // maybe reference_to_sinks() it's ok, not tested
3392  // we are in this case for the array I think
3393  pips_user_warning("Want to analyse constant path, but don't have a constant path : %s\n", reference_to_string(rlhs));
3394  // tf = assign_rhs_to_cp_to_transformer( cp , rhs, pre, ef);
3395  }
3396  }
3397 
3398  return tf;
3399 }
bool can_be_constant_path_p(reference)
TODO most of the time return same result that !effect_reference_dereferencing_p for the moment want t...
Definition: type.c:1492
entity update_operator_to_regular_operator(entity op)
Returns the binary operator associated to a C update operator such as +=.
Definition: entity.c:2154
static transformer update_cp_with_rhs_to_transformer(reference __attribute__((unused)) cp, expression __attribute__((unused)) rhs, transformer __attribute__((unused)) pre, list __attribute__((unused)) ef)
see assign_rhs_to_cp_to_transformer and update_reflhs_with_rhs_to_transformer to make update_cp_with_...

References any_scalar_assign_to_transformer(), can_be_constant_path_p(), constant_path_analyzed_p(), copy_expression(), ENDP, entity_to_expression(), free_expression(), MakeBinaryCall(), pips_user_warning, reference_indices, reference_to_string(), reference_variable, transformer_undefined, update_cp_with_rhs_to_transformer(), and update_operator_to_regular_operator().

Referenced by any_update_to_transformer().

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

◆ user_call_to_transformer()

transformer user_call_to_transformer ( entity  f,
list  pc,
transformer  pre,
list  ef 
)
Parameters
pcc
prere
eff

Definition at line 2506 of file ri_to_transformers.c.

2510 {
2512 
2513  pips_debug(7, "begin\n");
2514  pips_assert("f is a module", entity_module_p(f));
2515 
2517  t_caller = effects_to_transformer(ef);
2518  }
2519  else {
2520  if(c_module_p(f))
2521  t_caller = c_user_call_to_transformer(f, pc, pre, ef);
2522  else
2523  t_caller = fortran_user_call_to_transformer(f, pc, ef);
2524  }
2525  pips_debug(7, "end\n");
2526  return t_caller;
2527 }
bool c_module_p(entity m)
Test if a module "m" is written in C.
Definition: entity.c:2777
bool entity_module_p(entity e)
Definition: entity.c:683

References c_module_p(), c_user_call_to_transformer(), effects_to_transformer(), entity_module_p(), f(), fortran_user_call_to_transformer(), get_bool_property(), pips_assert, pips_debug, SEMANTICS_INTERPROCEDURAL, and transformer_undefined.

Referenced by call_to_transformer(), and expression_to_transformer().

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

◆ user_function_call_to_transformer()

transformer user_function_call_to_transformer ( entity  e,
expression  expr,
transformer  pre 
)

a function call is a call to a non void function in C and to a FUNCTION in Fortran

its precondition

Parameters
expra value
prea call to a function

Definition at line 1373 of file ri_to_transformers.c.

1377 {
1379  call c = expression_call(expr);
1380  entity f = call_function(c);
1381 
1382  if(c_module_p(f))
1383  tf = c_user_function_call_to_transformer(e, expr, pre);
1384  else
1385  tf = fortran_user_function_call_to_transformer(e, expr, pre);
1386 
1387  return tf;
1388 }
call expression_call(expression e)
Definition: expression.c:445
static transformer c_user_function_call_to_transformer(entity e, expression expr, transformer pre)
The Fortran and C versions are about the same.
static transformer fortran_user_function_call_to_transformer(entity e, expression expr, transformer __attribute__((unused)) pre)
its precondition

References c_module_p(), c_user_function_call_to_transformer(), call_function, expression_call(), f(), fortran_user_function_call_to_transformer(), and transformer_undefined.

Referenced by call_to_transformer(), float_call_expression_to_transformer(), integer_call_expression_to_transformer(), logical_expression_to_transformer(), and pointer_call_expression_to_transformer().

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