27 #ifdef BUILDER_INDUCTION_SUBSTITUTION
30 #include "pips_config.h"
61 bool substitution_occured_p;
72 bool is_modified =
false;
93 if( is_modified_entity_in_transformer(t,(
entity)v ) ) {
107 static bool decrement_call_p(
call c ) {
116 static bool increment_call_p(
call c ) {
126 static bool post_inc_or_de_crement_call_p(
call c) {
142 static void reference_substitute(
expression e, substitute_ctx *ctx ) {
194 static bool substitute_in_call(
call c, substitute_ctx *ctx) {
195 entity induction_variable_candidate = ctx->to_substitute;
221 bool increment_p = increment_call_p( c );
222 bool decrement_p = decrement_call_p( c );
224 if(increment_p || decrement_p ) {
225 if( increment_call_p( c ) ) {
229 }
else if( decrement_call_p( c ) ) {
240 expression substitute_on = get_right_part_of_assignment( c );
247 reference_substitute );
279 pips_debug( 1,
"Before update assignment : " );
297 if(post_inc_or_de_crement_call_p(c)) {
323 ctx->substitution_occured_p =
true;
326 pips_debug( 1,
"Unsugar update assignment : " );
343 static bool expression_subtitution_on_call(
expression substitute,
344 entity induction_variable_candidate,
348 pips_debug(1,
"Induction substitution : %s => ",
351 fprintf(stderr,
" on call : " );
357 ctx.to_substitute = induction_variable_candidate;
358 ctx.substitute_by = substitute;
359 ctx.substitution_occured_p =
false;
360 ctx.root_instruction = root_instruction;
364 return ctx.substitution_occured_p;
375 static bool subtitute_induction_statement_in(
statement s ) {
437 bool found_loop_index =
false;
440 int induction_variable_candidate_coeff = 0;
455 found_loop_index =
true;
461 }
else if ( coeff == 1 ) {
473 pips_debug(5,
"We already have an induction candidate for this"
474 "equation (%s) and encounter a new one (%s), so skip "
483 induction_variable_candidate = v;
486 induction_variable_candidate_coeff = -coeff;
494 substitute = local_expr;
514 if ( found_loop_index ) {
520 pips_debug(4,
"Induction variable candidate found : %s\n",
523 pips_debug(4,
"No Induction variable candidate found !\n");
525 if ( induction_variable_candidate_coeff != 0) {
531 pips_debug(4,
"The substitute expression is ");
535 pips_debug(4,
"The substitute expression is undefined.\n");
537 if( is_modified_entity_in_transformer(
539 induction_variable_candidate ) ) {
540 pips_debug(4,
"Variable is modified by this statement\n");
542 pips_debug(4,
"Variable is not modified by this statement\n");
546 if ( found_loop_index
550 && induction_variable_candidate_coeff != 0
556 if ( induction_variable_candidate_coeff == -1 ) {
562 }
else if ( induction_variable_candidate_coeff != 1 ) {
570 induction_variable_candidate )) {
572 expression_subtitution_on_call(substitute,
573 induction_variable_candidate,
579 ctx.to_substitute = induction_variable_candidate;
580 ctx.substitute_by = substitute;
581 ctx.substitution_occured_p =
false;
627 debug_on(
"INDUCTION_SUBSTITUTION_DEBUG_LEVEL" );
631 pips_debug(6,
"finding enclosing loops ...\n");
661 bool good_result_p =
true;
663 return ( good_result_p );
call make_call(entity a1, list a2)
expression copy_expression(expression p)
EXPRESSION.
syntax copy_syntax(syntax p)
SYNTAX.
void free_syntax(syntax p)
void transformer_free(transformer t)
transformer empty_transformer(transformer t)
Do not allocate an empty transformer, but transform an allocated transformer into an empty_transforme...
#define CONTRAINTE_UNDEFINED_P(c)
#define contrainte_succ(c)
#define contrainte_vecteur(c)
passage au champ vecteur d'une contrainte "a la Newgen"
void reset_proper_rw_effects(void)
void set_proper_rw_effects(statement_effects)
void set_cumulated_rw_effects(statement_effects)
void reset_cumulated_rw_effects(void)
const char * module_name(const char *s)
Return the module part of an entity name.
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
#define gen_recurse(start, domain_number, flt, rwt)
int gen_consistent_p(gen_chunk *obj)
GEN_CONSISTENT_P dynamically checks the type correctness of OBJ.
void reset_current_module_entity(void)
Reset the current module entity.
void reset_current_module_statement(void)
Reset the current module statement.
statement set_current_module_statement(statement)
Set the current module statement.
statement get_current_module_statement(void)
Get the current module statement.
entity set_current_module_entity(entity)
static.c
entity get_current_module_entity(void)
Get the entity of the current module.
void gen_null2(__attribute__((unused)) void *u1, __attribute__((unused)) void *u2)
idem with 2 args, to please overpeaky compiler checks
bool gen_true2(__attribute__((unused)) gen_chunk *u1, __attribute__((unused)) void *u2)
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
bool native_call_p(call c, string op_name)
Test if a call is a native instruction of the language.
void clean_enclosing_loops(void)
bool index_of_a_loop_p(Variable v, list loops)
Check if variable v is an index for an enclosing loop.
statement_mapping loops_mapping_of_statement(statement stat)
#define ENDP(l)
Test if a list is empty.
#define POP(l)
Modify a list pointer to point on the next element of the list.
#define NIL
The empty list (nil in Lisp)
size_t gen_length(const list l)
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
#define CAR(pcons)
Get the value of the first element of a list.
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
#define CDR(pcons)
Get the list less its first element.
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
#define DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
bool statement_loop_p(statement)
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
normalized NormalizeExpression(expression e)
normalize.c
void print_syntax(syntax s)
void print_expression(expression e)
no file descriptor is passed to make is easier to use in a debugging stage.
void print_statement(statement)
Print a statement on stderr.
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
#define POST_DECREMENT_OPERATOR_NAME
#define MINUS_OPERATOR_NAME
#define DIVIDE_UPDATE_OPERATOR_NAME
#define COMMA_OPERATOR_NAME
#define PLUS_OPERATOR_NAME
#define MULTIPLY_UPDATE_OPERATOR_NAME
#define MINUS_UPDATE_OPERATOR_NAME
#define PRE_DECREMENT_OPERATOR_NAME
#define DIVIDE_OPERATOR_NAME
#define UNARY_MINUS_OPERATOR_NAME
#define PRE_INCREMENT_OPERATOR_NAME
#define POST_INCREMENT_OPERATOR_NAME
#define PLUS_UPDATE_OPERATOR_NAME
#define MULTIPLY_OPERATOR_NAME
#define ASSIGN_OPERATOR_NAME
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...
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
bool expression_call_p(expression e)
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
call expression_call(expression e)
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
expression make_op_exp(char *op_name, expression exp1, expression exp2)
================================================================
expression MakeUnaryCall(entity f, expression a)
Creates a call expression to a function with one argument.
bool expression_reference_p(expression e)
Test if an expression is a reference.
bool is_expression_reference_to_entity_p(expression e, entity v)
Test if an expression is a reference to a given variable entity.
expression call_to_expression(call c)
Build an expression that call a function or procedure.
list load_statement_enclosing_loops(statement)
void set_enclosing_loops_map(statement_mapping)
#define normalized_undefined
#define syntax_reference_p(x)
#define expression_domain
newgen_execution_domain_defined
#define syntax_reference(x)
#define reference_variable(x)
#define call_undefined_p(x)
#define statement_domain
newgen_sizeofexpression_domain_defined
#define call_domain
newgen_callees_domain_defined
#define EXPRESSION(x)
EXPRESSION.
#define entity_undefined_p(x)
#define expression_undefined
#define transformer_relation(x)
#define expression_normalized(x)
#define transformer_arguments(x)
#define instruction_call_p(x)
#define expression_undefined_p(x)
#define test_condition(x)
#define statement_instruction(x)
#define instruction_call(x)
#define instruction_test_p(x)
#define call_arguments(x)
#define instruction_test(x)
#define expression_syntax(x)
#define predicate_system(x)
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
void module_to_value_mappings(entity m)
void module_to_value_mappings(entity m): build hash tables between variables and values (old,...
text text_transformer(transformer tran)
text text_transformer(transformer tran) input : a transformer representing a transformer or a precond...
transformer load_statement_precondition(statement)
void set_transformer_map(statement_mapping)
transformer load_statement_transformer(statement)
void reset_precondition_map(void)
void set_precondition_map(statement_mapping)
void reset_transformer_map(void)
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
The structure used to build lists in NewGen.
void dump_text(text t)
FI: print_text() should be fprint_text() and dump_text(), print_text()
A gen_chunk is used to store every object.
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
void * Variable
arithmetique is a requirement for vecteur, but I do not want to inforce it in all pips files....