PIPS
|
#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"
Go to the source code of this file.
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
args | rgs |
ef | arguments for assign |
pre | effects of assign |
Definition at line 3177 of file ri_to_transformers.c.
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().
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
op | p |
args | rgs |
ef | arguments for update |
pre | effects of assign |
Definition at line 3525 of file ri_to_transformers.c.
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().
transformer any_scalar_assign_to_transformer | ( | entity | v, |
expression | rhs, | ||
list | ef, | ||
transformer | pre | ||
) |
precondition
rhs | hs |
ef | f |
pre | effects of assign |
Definition at line 2832 of file ri_to_transformers.c.
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().
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
v | entity/variable to be assign |
rhs | expression/value to assign |
pre | precondition, transformer already present |
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);
rhs | hs |
pre | re |
Definition at line 2766 of file ri_to_transformers.c.
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().
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
op | p |
args | rgs |
ef | arguments for update |
pre | effects of assign |
Definition at line 3401 of file ri_to_transformers.c.
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().
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.
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().
|
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
tf | transformer |
e | abstract write effects |
apply_p | if we apply or add an effect, true if we apply |
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.
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().
|
static |
Definition at line 469 of file ri_to_transformers.c.
References expression_undefined, and generic_apply_effects_to_transformer().
Referenced by statement_to_transformer().
|
static |
Definition at line 464 of file ri_to_transformers.c.
References generic_apply_effects_to_transformer().
Referenced by any_assign_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.
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().
|
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(¤t_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
tf | transformer |
e | write effect (assumed), on a concrete location (assumed) |
rhs | some expression. more or less linked to the effect, useful if error r warning messages are emitted |
Definition at line 129 of file ri_to_transformers.c.
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().
|
static |
Definition at line 459 of file ri_to_transformers.c.
References generic_apply_effects_to_transformer().
Referenced by effects_to_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.
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.
|
static |
cp | constant path to be assign (the caller need to verify that cp is really a constant path) |
rhs | expression to assign |
pre | precondition |
ef | effects of assign |
Definition at line 2852 of file ri_to_transformers.c.
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().
|
static |
rlhs | reference to be assigned |
rhs | expression assigned |
pre | precondition (range of a precondition?) |
ef | effects of 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.
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().
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);
expr | xpr |
pre | re |
Definition at line 2595 of file ri_to_transformers.c.
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().
|
static |
op | update operator |
rlhs | reference to be update |
rhs | expression to assign |
pre | precondition |
ef | effects of assign |
Definition at line 3479 of file ri_to_transformers.c.
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().
|
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.
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().
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.
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().
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
pc | c |
pre | re |
ef | f |
Definition at line 2196 of file ri_to_transformers.c.
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().
|
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
expr | a value |
pre | a call to a function |
Definition at line 1165 of file ri_to_transformers.c.
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().
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);
pre | re |
ef | f |
Definition at line 1044 of file ri_to_transformers.c.
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().
transformer complete_non_identity_statement_transformer | ( | transformer | t, |
transformer | pre, | ||
statement | s | ||
) |
FI: only implemented for while loops.
pre | re |
Definition at line 3685 of file ri_to_transformers.c.
References generic_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.
pre | re |
Definition at line 3677 of file ri_to_transformers.c.
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().
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
pre | re |
Definition at line 580 of file ri_to_transformers.c.
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().
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);
dl | l |
pre | re |
Definition at line 649 of file ri_to_transformers.c.
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().
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.
pre | re |
Definition at line 535 of file ri_to_transformers.c.
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().
list of effects
algorithm: keep only write effects on scalar variable with values
fx | x |
Definition at line 798 of file ri_to_transformers.c.
References action_write_p, arguments_add_entity(), EFFECT, effect_action, effect_any_reference, entity_has_values_p(), FOREACH, NIL, and reference_variable.
transformer effects_to_transformer | ( | list | e | ) |
list of effects
Definition at line 474 of file ri_to_transformers.c.
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().
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);
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.
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().
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.
pc | c |
ef | f |
Definition at line 2269 of file ri_to_transformers.c.
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().
|
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));
expr | a value |
pre | a call to a function |
Definition at line 1248 of file ri_to_transformers.c.
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().
|
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.
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().
|
static |
Apply or add an effect e on a transformer tf only a write effect has an impact
tf | transformer |
e | a write effect on the store (check performed by the caller) |
apply_p | if we apply or add an effect, true if we apply |
rhs | redundant with apply_p |
additional_p | neglect effects that are already expressed by the transformer arguments |
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.
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().
|
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.
tf | transformer (modified by side effect) |
el | list of effects |
apply_p | if we apply or add the list of effect, true if we apply |
rhs | |
additional_p | do not rewrite variables that have already been modified in tf |
abstract_p | only exploit abstract effects |
algorithm: keep only memory write effects on variables with values
Definition at line 414 of file ri_to_transformers.c.
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().
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...
pre | re |
identity_p | dentity_p |
Definition at line 3706 of file ri_to_transformers.c.
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().
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.
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().
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
tf | f |
le | e |
preserve_rv_p | reserve_rv_p |
Definition at line 1398 of file ri_to_transformers.c.
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().
|
static |
effects associated to instruction i
Definition at line 3599 of file ri_to_transformers.c.
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().
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
lhs | hs |
rhs | hs |
pre | re |
ef | f |
Definition at line 2693 of file ri_to_transformers.c.
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.
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
pc | c |
pre | re |
ef | f |
Definition at line 911 of file ri_to_transformers.c.
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().
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.
tf | f |
fr | r |
ar | r |
Definition at line 1723 of file ri_to_transformers.c.
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().
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.
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().
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.
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().
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.
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().
Number of formal parameters in pl before a vararg is reached.
The varargs are not analyzed.
pl | l |
Definition at line 1518 of file ri_to_transformers.c.
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().
|
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.
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().
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 ?
expr | xpr |
pre | re |
Definition at line 2651 of file ri_to_transformers.c.
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().
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
spre | pre |
Definition at line 3759 of file ri_to_transformers.c.
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().
|
static |
r | reference to a struct |
t | type of v, which much be matched by rhs expression type and which must not contain any named type |
rhs | right-hand side expression |
ef | list of effects |
pre | precondition of the assignment |
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.
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().
transformer struct_reference_assignment_to_transformer | ( | reference | r, |
type | t, | ||
expression | rhs, | ||
transformer | pre, | ||
list | ef | ||
) |
rhs | hs |
pre | re |
ef | f |
Definition at line 3078 of file ri_to_transformers.c.
References struct_reference_assignment_or_equality_to_transformer().
Referenced by assign_rhs_to_reflhs_to_transformer(), and struct_variable_assignment_to_transformer().
transformer struct_reference_equality_to_transformer | ( | reference | r, |
type | t, | ||
expression | rhs, | ||
transformer | pre, | ||
list | ef | ||
) |
rhs | hs |
pre | re |
ef | f |
Definition at line 3083 of file ri_to_transformers.c.
References struct_reference_assignment_or_equality_to_transformer().
Referenced by struct_variable_equality_to_transformer().
transformer struct_variable_assignment_to_transformer | ( | entity | v, |
type | t, | ||
expression | rhs, | ||
transformer | pre, | ||
list | ef | ||
) |
v | assigned struct variable (does not handle the general case, "e1==e2;" where e1 and e2 are lhs expressions |
t | type of v, which much be matched by rhs expression type and which must not contain any named type |
rhs | right-hand side expression |
ef | list of effects |
pre | precondition of the assignment |
rhs | hs |
pre | re |
ef | f |
Definition at line 3100 of file ri_to_transformers.c.
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().
transformer struct_variable_equality_to_transformer | ( | entity | v, |
type | t, | ||
expression | rhs, | ||
transformer | pre, | ||
list | ef | ||
) |
rhs | hs |
pre | re |
ef | f |
Definition at line 3108 of file ri_to_transformers.c.
References free_reference(), make_reference(), NIL, and struct_reference_equality_to_transformer().
Referenced by any_user_call_site_to_transformer().
transformer substitute_formal_array_elements_in_precondition | ( | transformer | tf, |
entity | f, | ||
list | pc, | ||
transformer | pre, | ||
list | ef | ||
) |
tf | f |
pc | c |
pre | re |
ef | f |
Definition at line 2014 of file ri_to_transformers.c.
References f(), and generic_substitute_formal_array_elements_in_transformer().
Referenced by process_call_for_summary_precondition().
transformer substitute_formal_array_elements_in_transformer | ( | transformer | tf, |
entity | f, | ||
list | pc, | ||
transformer | pre, | ||
list | ef | ||
) |
tf | f |
pc | c |
pre | re |
ef | f |
Definition at line 2009 of file ri_to_transformers.c.
References f(), and generic_substitute_formal_array_elements_in_transformer().
Referenced by c_user_call_to_transformer().
|
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.
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().
transformer transformer_apply_field_assignments | ( | transformer | t, |
reference | l, | ||
reference | r, | ||
type | st | ||
) |
st | t |
Definition at line 2925 of file ri_to_transformers.c.
References transformer_apply_field_assignments_or_equalities().
Referenced by struct_reference_assignment_or_equality_to_transformer(), and 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.
st | t |
assign_p | ssign_p |
Definition at line 2876 of file ri_to_transformers.c.
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().
transformer transformer_apply_field_equalities | ( | transformer | t, |
reference | l, | ||
reference | r, | ||
type | st | ||
) |
st | t |
Definition at line 2930 of file ri_to_transformers.c.
References transformer_apply_field_assignments_or_equalities().
Referenced by struct_reference_assignment_or_equality_to_transformer().
transformer transformer_apply_unknown_field_assignments | ( | transformer | t, |
reference | l, | ||
type | st | ||
) |
st | t |
Definition at line 2976 of file ri_to_transformers.c.
References transformer_apply_unknown_field_assignments_or_equalities().
Referenced by struct_reference_assignment_or_equality_to_transformer().
|
static |
Simplified version of transformer_apply_field_assignments() with an unknown rhs.
Definition at line 2938 of file ri_to_transformers.c.
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().
transformer transformer_apply_unknown_field_equalities | ( | transformer | t, |
reference | l, | ||
type | st | ||
) |
st | t |
Definition at line 2981 of file ri_to_transformers.c.
References transformer_apply_unknown_field_assignments_or_equalities().
Referenced by struct_reference_assignment_or_equality_to_transformer().
|
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.
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().
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.
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().
transformer transformer_intra_to_inter | ( | transformer | tf, |
list | le | ||
) |
tf | f |
le | e |
Definition at line 1510 of file ri_to_transformers.c.
References generic_transformer_intra_to_inter().
Referenced by generic_module_name_to_transformers(), module_name_to_total_preconditions(), and program_precondition().
|
static |
see assign_rhs_to_cp_to_transformer and update_reflhs_with_rhs_to_transformer to make update_cp_with_rhs_to_transformer
cp | constant path to be assign (the caller need to verify that cp is really a constant path) |
rhs | expression to assign |
pre | precondition |
ef | effects of assign |
Definition at line 3321 of file ri_to_transformers.c.
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().
|
static |
op | update operator |
rlhs | reference to update |
rhs | expression to assign |
pre | precondition |
ef | effects of assign |
Definition at line 3351 of file ri_to_transformers.c.
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().
transformer user_call_to_transformer | ( | entity | f, |
list | pc, | ||
transformer | pre, | ||
list | ef | ||
) |
pc | c |
pre | re |
ef | f |
Definition at line 2506 of file ri_to_transformers.c.
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().
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
expr | a value |
pre | a call to a function |
Definition at line 1373 of file ri_to_transformers.c.
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().