PIPS
|
#include <stdio.h>
#include <string.h>
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "effects.h"
#include "text.h"
#include "text-util.h"
#include "database.h"
#include "resources.h"
#include "control.h"
#include "ri-util.h"
#include "prettyprint.h"
#include "effects-util.h"
#include "pipsdbm.h"
#include "misc.h"
#include "properties.h"
#include "effects-generic.h"
#include "effects-simple.h"
#include "transformer.h"
#include "semantics.h"
#include "arithmetique.h"
#include "expressions.h"
Go to the source code of this file.
Data Structures | |
struct | perform_switch |
Macros | |
#define | PERFORM_ADDITION 1 |
#define | PERFORM_SUBTRACTION 2 |
#define | PERFORM_MULTIPLICATION 3 |
#define | PERFORM_DIVISION 4 |
#define | PERFORM_C_DIVISION 14 |
#define | PERFORM_POWER 5 |
#define | PERFORM_MODULO 6 |
#define | PERFORM_C_MODULO 16 |
#define | PERFORM_MINIMUM 7 |
#define | PERFORM_MAXIMUM 8 |
Variables | |
static eformat_t | eformat_undefined = {expression_undefined, 1, 0, false} |
Hypotheses pour l'implementation: More... | |
static list | live_loop_indices = list_undefined |
when formating is useless (ie. More... | |
static statement | partial_eval_current_statement =statement_undefined |
static struct perform_switch | binary_operator_switch [] |
#define PERFORM_ADDITION 1 |
Definition at line 716 of file partial_eval.c.
#define PERFORM_C_DIVISION 14 |
Definition at line 720 of file partial_eval.c.
#define PERFORM_C_MODULO 16 |
Definition at line 723 of file partial_eval.c.
#define PERFORM_DIVISION 4 |
Definition at line 719 of file partial_eval.c.
#define PERFORM_MAXIMUM 8 |
Definition at line 725 of file partial_eval.c.
#define PERFORM_MINIMUM 7 |
Definition at line 724 of file partial_eval.c.
#define PERFORM_MODULO 6 |
Definition at line 722 of file partial_eval.c.
#define PERFORM_MULTIPLICATION 3 |
Definition at line 718 of file partial_eval.c.
#define PERFORM_POWER 5 |
Definition at line 721 of file partial_eval.c.
#define PERFORM_SUBTRACTION 2 |
Definition at line 717 of file partial_eval.c.
|
static |
Definition at line 157 of file partial_eval.c.
References CONS, ENTITY, gen_nconc(), live_loop_index_p(), live_loop_indices, NIL, and pips_assert.
Referenced by partial_eval_statement().
void dump_live_loop_indices | ( | void | ) |
Definition at line 145 of file partial_eval.c.
References dump_arguments(), list_undefined, live_loop_indices, and pips_assert.
should not require anything about expr
ie expression_eq(ef1.expr, ef2.expr)
ef1 | f1 |
ef2 | f2 |
Definition at line 269 of file partial_eval.c.
References eformat::expr, eformat::icoef, and eformat::ishift.
Referenced by partial_eval_expression_and_copy(), and regenerate_expression().
ent | nt |
fx | x |
Definition at line 198 of file partial_eval.c.
References action_kind_store_p, action_write_p, CAR, EFFECT, effect_action, effect_action_kind(), effect_any_reference, effects_effects, effects_undefined, ENDP, MAPL, pips_internal_error, reference_indices, reference_variable, and same_entity_p().
Referenced by partial_eval_reference().
expression generate_monome | ( | int | coef, |
expression | expr | ||
) |
coef | oef |
expr | xpr |
Definition at line 1623 of file partial_eval.c.
References entity_intrinsic(), expression_undefined, int_to_expression(), MakeBinaryCall(), MakeUnaryCall(), MULTIPLY_OPERATOR_NAME, pips_assert, and UNARY_MINUS_OPERATOR_NAME.
Referenced by partial_eval_binary_operator_old(), and partial_eval_plus_or_minus_operator().
void init_use_preconditions | ( | const char * | module_name | ) |
module_name | odule_name |
Definition at line 216 of file partial_eval.c.
References db_get_memory_resource(), get_debug_level(), get_precondition_map(), hash_table_undefined, module_name(), pips_assert, set_precondition_map(), and transformer_map_print().
Referenced by partial_eval().
void init_use_proper_effects | ( | const char * | module_name | ) |
module_name | odule_name |
Definition at line 171 of file partial_eval.c.
References db_get_memory_resource(), module_name(), pips_assert, proper_rw_effects_undefined_p(), and set_proper_rw_effects().
Referenced by partial_eval().
Definition at line 151 of file partial_eval.c.
References entity_is_argument_p(), list_undefined, live_loop_indices, and pips_assert.
Referenced by add_live_loop_index(), and partial_eval_reference().
bool partial_eval | ( | const char * | module_name | ) |
Top-level function.
be carrefull not to get any mapping before the code
DBR_CODE will be changed: argument "pure" is true because partial_eval() modifies DBR_CODE.
still bugs in dbm because effects are stored on disc after this phase
uses set_proper_effects_map
preconditions may need to print preconditions for debugging purposes
Reorder the module, because new statements may have been generated.
module_name | odule_name |
Definition at line 1832 of file partial_eval.c.
References db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, free_statement_global_stack(), free_value_mappings(), gen_recurse, gen_true(), get_current_module_entity(), get_current_module_statement(), init_use_preconditions(), init_use_proper_effects(), local_name_to_top_level_entity(), make_statement_global_stack(), module, module_name(), module_reorder(), module_statement, module_to_value_mappings(), partial_eval_statement(), reset_cumulated_rw_effects(), reset_current_module_entity(), reset_current_module_statement(), reset_live_loop_indices(), reset_precondition_map(), reset_proper_rw_effects(), set_cumulated_rw_effects(), set_current_module_entity(), set_current_module_statement(), set_live_loop_indices(), and statement_domain.
some more optimization if a neutral element has been generated
se some partial eval dark magic
se some partial eval dark magic
func | unc |
la | a |
ps | s |
fx | x |
Definition at line 1248 of file partial_eval.c.
References perform_switch::binary_operator, binary_operator_switch, CDR, eformat_undefined, entity_local_name(), entity_undefined_p, eformat::expr, expression_to_entity(), gen_length(), eformat::icoef, operator_neutral_element(), partial_eval_expression(), partial_eval_expression_and_regenerate(), pips_assert, REFCAR, same_entity_p(), and eformat::simpler.
Referenced by partial_eval_call().
FI: The C divide operator may be defined differently for negative integers
FI: The C modulo operator may be defined differently for negative integers
generate ef.icoef and ef.expr
factorize
addition
substraction e1-e2
substraction e2-e1
generate without factorize
not precise ??
generate ef.ishift
simplify shifts
exchange ef1 and ef2 (see later)
cannot optimize
exchange ef1 and ef2 (see later)
here we know that ef1.ecoef==0 and ef2.ecoef!=0
integer division does NOT commute with in any
multiplication -> only performed if "exact"
refer to Fortran77 chap 6.1.5
tocken==PERFORM_MODULO
func | unc |
la | a |
ps | s |
fx | x |
Definition at line 1308 of file partial_eval.c.
References C_MODULO_OPERATOR_NAME, CDR, DIVIDE_OPERATOR_NAME, eformat_undefined, entity_intrinsic(), entity_local_name(), eformat::expr, expression_undefined, FORTRAN_DIV, FORTRAN_MOD, gen_length(), generate_monome(), eformat::icoef, eformat::ishift, MakeBinaryCall(), MINUS_OPERATOR_NAME, MODULO_OPERATOR_NAME, MULTIPLY_OPERATOR_NAME, partial_eval_expression_and_copy(), partial_eval_expression_and_regenerate(), PERFORM_ADDITION, PERFORM_DIVISION, PERFORM_MODULO, PERFORM_MULTIPLICATION, PERFORM_SUBTRACTION, pips_assert, PLUS_OPERATOR_NAME, REFCAR, regenerate_expression(), eformat::simpler, and user_error.
eformat_t partial_eval_c_mod_operator | ( | expression * | ep1, |
expression * | ep2, | ||
Psysteme | ps, | ||
effects | fx | ||
) |
ep1 | p1 |
ep2 | p2 |
ps | s |
fx | x |
Definition at line 1079 of file partial_eval.c.
References partial_eval_div_or_mod_operator(), and PERFORM_C_MODULO.
it might be an intrinsic function
FI: The actual aruments are not partially evaluated? SG: no it's not, I fixed this
FI: Actually, the parameter mode should be checked. And the actual effects.
Note FI: the result obtained for the call to fx in Transformations/eval.c is correct, but I do not understand why. Actual parameters must be evaluated somewhere else.
value passing
the partial evaluation could be further improved by checking if there is a write effect on the corresponding formal parameter
This is dealt for using fx when dealing with a reference
ec | c |
ps | s |
fx | x |
Definition at line 574 of file partial_eval.c.
References c_language_module_p(), call_arguments, call_function, CAR, eformat_undefined, ENDP, entity_initial, eformat::expr, EXPRESSION, EXPRESSION_, expression_reference_p(), expression_undefined, fortran_language_module_p(), gen_length(), eformat::icoef, integer_constant_p(), integer_symbolic_constant_p(), is_value_code, is_value_constant, is_value_intrinsic, is_value_symbolic, is_value_unknown, eformat::ishift, MAPL, partial_eval_binary_operator(), partial_eval_expression_and_regenerate(), partial_eval_unary_operator(), pips_internal_error, POP, eformat::simpler, and value_tag.
Referenced by partial_eval_call_and_regenerate(), and partial_eval_call_expression().
FI: if the call is an operator, it is not part of the simplification; e.g. "3+5;"
ca | a |
ps | s |
fx | x |
Definition at line 553 of file partial_eval.c.
References call_undefined, partial_eval_call(), pips_assert, and regenerate_call().
Referenced by partial_eval_statement().
eformat_t partial_eval_call_expression | ( | expression | exp, |
Psysteme | ps, | ||
effects | fx | ||
) |
exp | xp |
ps | s |
fx | x |
Definition at line 664 of file partial_eval.c.
References exp, expression_syntax, partial_eval_call(), pips_assert, syntax_call, and syntax_call_p.
Referenced by partial_eval_syntax().
assumes conditions checked by partial_eval_declarations()
partial evaluation of expressions in dimensions and of initialization expression.
See if the dimensions can be simplified
See if the initialization expression can be simplified
FI: Lots of short cuts about side effects: pre and fx should be recomputed between each partial evaluation by the caller...
Too bad for the memory leak of entity_initial() but I'm afraid the expression might be shared
pre_sc | re_sc |
fx | x |
Definition at line 1648 of file partial_eval.c.
References DIMENSION, dimension_lower, dimension_upper, entity_initial, entity_type, expression_undefined_p, FOREACH, make_value_expression(), partial_eval_expression_and_regenerate(), type_variable, variable_dimensions, and variable_initial_expression().
Referenced by partial_eval_declarations().
el | l |
pre_sc | re_sc |
fx | x |
Definition at line 1672 of file partial_eval.c.
References ENTITY, entity_variable_p, FOREACH, partial_eval_declaration(), and variable_entity_p().
Referenced by partial_eval_statement().
eformat_t partial_eval_div_operator | ( | expression * | ep1, |
expression * | ep2, | ||
Psysteme | ps, | ||
effects | fx | ||
) |
ep1 | p1 |
ep2 | p2 |
ps | s |
fx | x |
Definition at line 1053 of file partial_eval.c.
References partial_eval_div_or_mod_operator(), and PERFORM_DIVISION.
eformat_t partial_eval_div_or_mod_operator | ( | int | token, |
expression * | ep1, | ||
expression * | ep2, | ||
Psysteme | ps, | ||
effects | fx | ||
) |
integer division does NOT commute with in any
multiplication -> only performed if "exact"
refer to Fortran77 chap 6.1.5
FI->SG: FORTRAN_DIV, SIGN_EQ, FORTRAN_MOD,... have been left in transformations-local.h when this code was moved into expressions. I haven't checked if they are used elsewhere. Could the expression library not dependent on transformations?
FI: C and Fortran modulo and division operators seem in fact equivalent, using negative modulo to maintain the equation
a == (a/b)*b+ab
instead of a positive remainder, i.e. modulo.
token | oken |
ep1 | p1 |
ep2 | p2 |
ps | s |
fx | x |
Definition at line 993 of file partial_eval.c.
References C_MODULO, eformat_undefined, eformat::expr, expression_undefined, FORTRAN_DIV, FORTRAN_MOD, eformat::icoef, eformat::ishift, partial_eval_expression_and_copy(), PERFORM_C_MODULO, PERFORM_DIVISION, PERFORM_MODULO, pips_internal_error, regenerate_expression(), eformat::simpler, and user_error.
Referenced by partial_eval_c_mod_operator(), partial_eval_div_operator(), and partial_eval_mod_operator().
eformat_t partial_eval_expression | ( | expression | e, |
Psysteme | ps, | ||
effects | fx | ||
) |
In case the expression is affine, use its affine form
FI: it would be better to test if ne is really simpler than e: it should contain fewer operators (1+1->2) or fewer references (n->1).
& !ef.icoef==0 && !ef.ishift==0
FI: it may be simpler because the simplification may be performed by normalize_expression()
ps | s |
fx | x |
Definition at line 318 of file partial_eval.c.
References eformat::expr, expression_normalized, expression_undefined_p, eformat::icoef, make_vecteur_expression(), NORMALIZE_EXPRESSION, normalized_linear, normalized_linear_p, partial_eval_syntax(), eformat::simpler, and unnormalize_expression().
Referenced by partial_eval_binary_operator(), partial_eval_expression_and_copy(), and partial_eval_expression_and_regenerate().
eformat_t partial_eval_expression_and_copy | ( | expression | expr, |
Psysteme | ps, | ||
effects | fx | ||
) |
expr | xpr |
ps | s |
fx | x |
Definition at line 305 of file partial_eval.c.
References eformat_equivalent_p(), eformat_undefined, eformat::expr, and partial_eval_expression().
Referenced by partial_eval_binary_operator_old(), partial_eval_div_or_mod_operator(), partial_eval_min_or_max_operator(), partial_eval_mult_operator(), partial_eval_plus_or_minus_operator(), partial_eval_power_operator(), partial_eval_unary_operator(), and partial_eval_update_operators().
void partial_eval_expression_and_regenerate | ( | expression * | ep, |
Psysteme | ps, | ||
effects | fx | ||
) |
ep | p |
ps | s |
fx | x |
Definition at line 284 of file partial_eval.c.
References expression_consistent_p(), ifdebug, partial_eval_expression(), pips_internal_error, print_eformat(), and regenerate_expression().
Referenced by do_solve_hardware_constraints_on_volume(), partial_eval_binary_operator(), partial_eval_binary_operator_old(), partial_eval_call(), partial_eval_declaration(), partial_eval_minus_c_operator(), partial_eval_plus_c_operator(), partial_eval_reference(), partial_eval_statement(), partial_eval_syntax(), and partial_eval_unary_operator().
eformat_t partial_eval_max_operator | ( | expression * | ep1, |
expression * | ep2, | ||
Psysteme | ps, | ||
effects | fx | ||
) |
ep1 | p1 |
ep2 | p2 |
ps | s |
fx | x |
Definition at line 1156 of file partial_eval.c.
References partial_eval_min_or_max_operator(), and PERFORM_MAXIMUM.
eformat_t partial_eval_min_operator | ( | expression * | ep1, |
expression * | ep2, | ||
Psysteme | ps, | ||
effects | fx | ||
) |
ep1 | p1 |
ep2 | p2 |
ps | s |
fx | x |
Definition at line 1143 of file partial_eval.c.
References partial_eval_min_or_max_operator(), and PERFORM_MINIMUM.
eformat_t partial_eval_min_or_max_operator | ( | int | token, |
expression * | ep1, | ||
expression * | ep2, | ||
Psysteme | ps, | ||
effects | fx | ||
) |
ep1-ep2 >= 0 -> min(ep1,ep2) == ep2 and max(ep1,ep2) == ep1
ep1-ep2 <= 0 -> min(ep1,ep2) == ep1 and max(ep1,ep2) == ep2
token | oken |
ep1 | p1 |
ep2 | p2 |
ps | s |
fx | x |
Definition at line 1092 of file partial_eval.c.
References copy_expression(), eformat_undefined, eformat::expr, expression_undefined, eformat::icoef, intptr_t, eformat::ishift, load_statement_precondition(), make_op_exp(), MAX, MIN, MINUS_OPERATOR_NAME, ok, partial_eval_current_statement, partial_eval_expression_and_copy(), PERFORM_MAXIMUM, precondition_minmax_of_expression(), regenerate_expression(), eformat::simpler, and transformer_range().
Referenced by partial_eval_max_operator(), and partial_eval_min_operator().
eformat_t partial_eval_minus_c_operator | ( | expression * | ep1, |
expression * | ep2, | ||
Psysteme | ps, | ||
effects | fx | ||
) |
ep1 | p1 |
ep2 | p2 |
ps | s |
fx | x |
Definition at line 972 of file partial_eval.c.
References b1, b2, basic_of_expression(), basic_pointer_p, eformat_undefined, free_basic(), partial_eval_expression_and_regenerate(), and partial_eval_minus_operator().
eformat_t partial_eval_minus_operator | ( | expression * | ep1, |
expression * | ep2, | ||
Psysteme | ps, | ||
effects | fx | ||
) |
ep1 | p1 |
ep2 | p2 |
ps | s |
fx | x |
Definition at line 959 of file partial_eval.c.
References partial_eval_plus_or_minus_operator(), and PERFORM_SUBTRACTION.
Referenced by partial_eval_minus_c_operator().
eformat_t partial_eval_mod_operator | ( | expression * | ep1, |
expression * | ep2, | ||
Psysteme | ps, | ||
effects | fx | ||
) |
ep1 | p1 |
ep2 | p2 |
ps | s |
fx | x |
Definition at line 1066 of file partial_eval.c.
References partial_eval_div_or_mod_operator(), and PERFORM_MODULO.
eformat_t partial_eval_mult_operator | ( | expression * | ep1, |
expression * | ep2, | ||
Psysteme | ps, | ||
effects | fx | ||
) |
exchange ef1 and ef2 (see later)
cannot optimize
exchange ef1 and ef2 (see later)
here we know that ef1.ecoef==0 and ef2.ecoef!=0
ep1 | p1 |
ep2 | p2 |
ps | s |
fx | x |
Definition at line 727 of file partial_eval.c.
References eformat_undefined, entity_intrinsic(), eformat::expr, expression_undefined, eformat::icoef, eformat::ishift, MakeBinaryCall(), MULTIPLY_OPERATOR_NAME, partial_eval_expression_and_copy(), regenerate_expression(), and eformat::simpler.
eformat_t partial_eval_plus_c_operator | ( | expression * | ep1, |
expression * | ep2, | ||
Psysteme | ps, | ||
effects | fx | ||
) |
ep1 | p1 |
ep2 | p2 |
ps | s |
fx | x |
Definition at line 937 of file partial_eval.c.
References b1, b2, basic_of_expression(), basic_pointer_p, eformat_undefined, free_basic(), partial_eval_expression_and_regenerate(), and partial_eval_plus_operator().
eformat_t partial_eval_plus_operator | ( | expression * | ep1, |
expression * | ep2, | ||
Psysteme | ps, | ||
effects | fx | ||
) |
ep1 | p1 |
ep2 | p2 |
ps | s |
fx | x |
Definition at line 924 of file partial_eval.c.
References partial_eval_plus_or_minus_operator(), and PERFORM_ADDITION.
Referenced by partial_eval_plus_c_operator().
eformat_t partial_eval_plus_or_minus_operator | ( | int | token, |
expression * | ep1, | ||
expression * | ep2, | ||
Psysteme | ps, | ||
effects | fx | ||
) |
Automatic tools sometimes generate source code like "i - i"
Could be improved with a commutative_expression_equal_p() if cases arise
FI: no idea of the expression should be copied or not, let's play safe.
Here we should go down to see if *ep1 can be partially evaluated
FI: here I should get rid of ef1...
generate ef.icoef and ef.expr
factorize icoef
addition
substraction e1-e2
substraction e2-e1
generate without factorize, but for -1?
not precise ??
CA (9/9/97) condition <0 added in order to simplify also expression like (J)+(-1) in (J-1)
FI: simplification i++ + 0? I do not understand Corinne's code above. ef.ishift is generated below. I force simpler because ef2.icoef==0 can result from a simplification
generate ef.ishift
simplify shifts
token | oken |
ep1 | p1 |
ep2 | p2 |
ps | s |
fx | x |
Definition at line 792 of file partial_eval.c.
References eformat_undefined, entity_intrinsic(), eformat::expr, expression_equal_p(), expression_undefined, generate_monome(), eformat::icoef, eformat::ishift, MakeBinaryCall(), MINUS_OPERATOR_NAME, partial_eval_expression_and_copy(), PERFORM_ADDITION, PERFORM_SUBTRACTION, pips_internal_error, PLUS_OPERATOR_NAME, and eformat::simpler.
Referenced by partial_eval_minus_operator(), and partial_eval_plus_operator().
eformat_t partial_eval_power_operator | ( | expression * | ep1, |
expression * | ep2, | ||
Psysteme | ps, | ||
effects | fx | ||
) |
ep1 | p1 |
ep2 | p2 |
ps | s |
fx | x |
Definition at line 1169 of file partial_eval.c.
References eformat_undefined, eformat::expr, expression_undefined, eformat::icoef, ipow(), eformat::ishift, partial_eval_expression_and_copy(), regenerate_expression(), and eformat::simpler.
eformat_t partial_eval_reference | ( | expression | e, |
Psysteme | ps, | ||
effects | fx | ||
) |
FI: this test may be wrong for enum variables? Does it matter? what can you do with enum anyway? Well, they can be replaced by their values
entity cannot be replaced
faire la Variable
verification de la presence de la variable dans ps
feasible = sc_minmax_of_variable(ps1, (Variable) var, &min, &max);
var is constant and has to be replaced
new_expr=int_to_expression((int)min);
replace expression_normalized(e) with expression_normalized(new_expr)
free_normalized(expression_normalized(e)); expression_normalized(e) = expression_normalized(new_expr); expression_normalized(new_expr) = normalized_undefined;
replace expression_syntax(e) with expression_syntax(new_expr)
return(entity_initial(call_function(syntax_call(expression_syntax(e)))));
ps | s |
fx | x |
Definition at line 436 of file partial_eval.c.
References base_contains_variable_p(), base_rm, BASE_UNDEFINED, basic_int_p, CAR, debug(), eformat_undefined, entity_name, entity_type, entity_written_p(), eformat::expr, EXPRESSION, EXPRESSION_, expression_syntax, expression_undefined, eformat::icoef, ifdebug, eformat::ishift, live_loop_index_p(), MAPL, max, min, NIL, partial_eval_expression_and_regenerate(), pips_assert, pips_debug, pips_internal_error, pips_user_warning, print_expression(), reference_indices, reference_variable, sc_dup(), sc_minmax_of_variable2(), sc_to_minimal_basis(), eformat::simpler, syntax_reference, syntax_reference_p, type_variable, type_variable_p, ultimate_type(), value_eq, VALUE_TO_INT, and variable_basic.
Referenced by partial_eval_syntax().
void partial_eval_statement | ( | statement | stmt | ) |
apply partial eval on each statement we cannot recurse on something other than a statement because we use the effects & preconditions attached to the statement
stmt | statement to partial_eval |
It is assumed that sub-expressions do not have side effects because the same precondition is used for all of them.
It would be simpler to transform instruction calls into instruction expression to have fewer cases to handle. Case instruction expression was introduced for C and made instruction call obsolete. The same is true for value: as expressions have been added, constant became redundant.
This is no longer useful with the new representation of C declarations.
Assuming no side-effects in loop bounds, sc is constant...
The whileloop precondition cannot be used to evaluate the while condition. It must be unioned with the body postcondition. partial_eval_expression_and_regenerate(&whileloop_condition(l), stmt_prec(stmt), stmt_to_fx(stmt,fx_map));
Also, two kinds of while must be handled
Short term fix... we might as well not try anything for the while condition
partial_eval_expression_and_regenerate(&whileloop_condition(l), SC_UNDEFINED, stmt_to_fx(stmt,fx_map));
stmt | tmt |
Definition at line 1695 of file partial_eval.c.
References add_live_loop_index(), declaration_statement_p(), ENTITY, entity_initial, FOREACH, forloop_condition, forloop_increment, forloop_initialization, get_debug_level(), get_proper_rw_effects(), ifdebug, instruction_call, instruction_expression, instruction_forloop, instruction_loop, instruction_tag, instruction_test, 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_index, loop_range, partial_eval_call_and_regenerate(), partial_eval_current_statement, partial_eval_declarations(), partial_eval_expression_and_regenerate(), pips_assert, pips_debug, pips_internal_error, pop_statement_global_stack(), print_statement(), push_statement_on_statement_global_stack(), range_increment, range_lower, range_upper, rm_live_loop_index(), statement_consistent_p(), statement_declarations, statement_instruction, statement_undefined, statement_undefined_p, stmt_prec(), stmt_to_fx(), test_condition, value_expression, and value_expression_p.
Referenced by partial_eval().
eformat_t partial_eval_syntax | ( | expression | e, |
Psysteme | ps, | ||
effects | fx | ||
) |
ps | s |
fx | x |
Definition at line 355 of file partial_eval.c.
References abort, application_function, cast_expression, eformat_undefined, ENDP, expression_syntax, get_bool_property(), get_debug_level(), int_to_entity(), is_syntax_application, is_syntax_call, is_syntax_cast, is_syntax_range, is_syntax_reference, is_syntax_sizeofexpression, is_syntax_subscript, is_syntax_va_arg, make_call(), make_syntax_call(), NIL, partial_eval_call_expression(), partial_eval_expression_and_regenerate(), partial_eval_reference(), pips_internal_error, POP, print_eformat(), REFCAR, sizeofexpression_expression, sizeofexpression_expression_p, sizeofexpression_type, subscript_array, subscript_indices, syntax_application, syntax_cast, syntax_sizeofexpression, syntax_subscript, syntax_tag, type_memory_size(), and update_expression_syntax().
Referenced by partial_eval_expression().
operator can be a pre/post inc/dec C operator
func | unc |
la | a |
ps | s |
fx | x |
Definition at line 680 of file partial_eval.c.
References eformat_undefined, ENTITY_ADDRESS_OF_P, ENTITY_UNARY_MINUS_P, gen_length(), eformat::icoef, eformat::ishift, partial_eval_expression_and_copy(), partial_eval_expression_and_regenerate(), pips_assert, REFCAR, and eformat::simpler.
Referenced by partial_eval_call().
eformat_t partial_eval_update_operators | ( | expression *ep1 | __attribute__(__unused__), |
expression * | ep2, | ||
Psysteme | ps, | ||
effects | fx | ||
) |
FI: a better job could be done by distinguishing between the different kinds of operators.
For instance "a+=0" or "b*=1;" could be simplified. For the time being, we simplify the two sub-expressions but not the current expression.
You do not want to change "n = 1; n = 1;" into n = 1; 1 = 1;"
Definition at line 1198 of file partial_eval.c.
References eformat_undefined, expression_reference(), expression_reference_p(), partial_eval_expression_and_copy(), reference_scalar_p(), and regenerate_expression().
void print_eformat | ( | eformat_t | ef, |
char * | name | ||
) |
ef | f |
name | ame |
Definition at line 277 of file partial_eval.c.
References eformat::expr, eformat::icoef, eformat::ishift, print_expression(), printf(), and eformat::simpler.
Referenced by partial_eval_expression_and_regenerate(), and partial_eval_syntax().
We are likely to end up in trouble because the regenerated expression may not be a call; for instance "n+0" is converted into a reference to n...
Nothing to do
We are in trouble...
Any memory write effect?
Do not change the initial call
We are even more in trouble
efp | fp |
ca | a |
Definition at line 1589 of file partial_eval.c.
References call_arguments, call_function, CONTINUE_FUNCTION_NAME, effects_all_read_p(), entity_intrinsic(), expression_call_p(), expression_reference_p(), expression_syntax, expression_to_proper_effects(), expression_undefined, expression_undefined_p, free_expression(), NIL, pips_internal_error, regenerate_expression(), and syntax_call.
Referenced by partial_eval_call_and_regenerate().
void regenerate_expression | ( | eformat_t * | efp, |
expression * | ep | ||
) |
in order to regenerate expression from eformat.
;
optimized so that it can be called for any compatible ef and *ep; result in *ep.
nothing to do because expressions are the same
simply free efp->expr
useless
?? ******commented out for debug*******
free_expression(*ep);
check
generate unary_minus
generate product
generate addition or substraction
check
final expression is constant efp->ishift
replace *ep by tmp_expr
efp | fp |
ep | p |
Definition at line 1526 of file partial_eval.c.
References ABS, eformat_equivalent_p(), eformat_undefined, entity_intrinsic(), eformat::expr, expression_undefined, get_bool_property(), eformat::icoef, int_to_expression(), eformat::ishift, MakeBinaryCall(), MakeUnaryCall(), MINUS_OPERATOR_NAME, MULTIPLY_OPERATOR_NAME, pips_assert, PLUS_OPERATOR_NAME, eformat::simpler, and UNARY_MINUS_OPERATOR_NAME.
Referenced by partial_eval_binary_operator_old(), partial_eval_div_or_mod_operator(), partial_eval_expression_and_regenerate(), partial_eval_min_or_max_operator(), partial_eval_mult_operator(), partial_eval_power_operator(), partial_eval_update_operators(), and regenerate_call().
void reset_live_loop_indices | ( | void | ) |
The index set should be empty when leaving partial eval
Definition at line 135 of file partial_eval.c.
References ENDP, free_arguments(), list_undefined, live_loop_indices, and pips_assert.
Referenced by partial_eval().
|
static |
Definition at line 164 of file partial_eval.c.
References arguments_rm_entity(), list_undefined, live_loop_indices, and pips_assert.
Referenced by partial_eval_statement().
void set_live_loop_indices | ( | void | ) |
cproto-generated files
Definition at line 129 of file partial_eval.c.
References list_undefined, live_loop_indices, NIL, and pips_assert.
Referenced by partial_eval().
pips_assert("stmt_prec", t != transformer_undefined);
stmt | tmt |
Definition at line 230 of file partial_eval.c.
References HASH_UNDEFINED_VALUE, load_statement_precondition(), pips_assert, pips_debug, predicate_system, statement_number, statement_ordering, statement_undefined, transformer_relation, and transformer_undefined.
Referenced by partial_eval_statement().
effects stmt_to_fx | ( | statement | stmt, |
statement_effects | fx_map | ||
) |
returns proper effects associated to statement stmt
stmt | tmt |
fx_map | x_map |
Definition at line 179 of file partial_eval.c.
References apply_statement_effects(), effects_effects, ifdebug, pips_assert, pips_debug, print_effects, statement_number, statement_ordering, and statement_undefined.
Referenced by partial_eval_statement().
void transformer_map_print | ( | void | ) |
Definition at line 252 of file partial_eval.c.
References f(), fprintf(), get_precondition_map(), HASH_MAP, hash_table_print_header(), print_transformer, statement_number, and statement_ordering.
Referenced by init_use_preconditions().
|
static |
Referenced by partial_eval_binary_operator().
|
static |
Hypotheses pour l'implementation:
Toute fonction d'evaluation partielle retourne eformat_undefined lorsqu'elle n'a rien evalue (ex: lors d'un appel d'une fonction externe).
eformat.expr NE DOIT JAMAIS partager de structures avec le code. Par contre, une expression detachee du code peut appartenir a eformat.expr.
Lorsqu'une expression est detachee du code, il faut prendre garde a la remplacer par expression_undefined. Sinon, le free (dans regenerate_expression()) causera des degas!
Si une information est ajoutee a eformat_undefined, alors l'expression est RECOPIEE. Pourtant, eformat.simpler reste false et l'expression d'origine n'est pas freee, car une seule information ne permet aucune simplification. A partir de la prise en compte de la seconde information, des qu'eformat est simplife', alors eformat.simpler devient vrai. L'expression d'origine sera alors free'e lorsque regenerate_expression().
Des que l'evaluation n'est plus possible, il faut regenerer l'expression.
Note FI: now NORMALIZE_EXPRESSION() is also used to simplify expressions and sub-expressions in partial_eval_expression() because automatic program transformations sometimes generate kind of stupid code such as "i-i+1" or "512-1". When a simplification occurs, no feedback is provided and the linearized version of the expression is assumed "simpler". Hence, "simpler" now means "may be simpler". See comments below in partial_eval_expression(). Also, I did not take time to understand the invariant for expression allocation and free. I'm very likely to have introduced memory leaks via the changes in partial_eval_expression().
Note FI: the interface is based on Psystemes instead of transformers, which makes maintenance and evolution harder. for print_effects() for module_to_value_mappings()
Definition at line 102 of file partial_eval.c.
Referenced by partial_eval_binary_operator(), partial_eval_binary_operator_old(), partial_eval_call(), partial_eval_div_or_mod_operator(), partial_eval_expression_and_copy(), partial_eval_min_or_max_operator(), partial_eval_minus_c_operator(), partial_eval_mult_operator(), partial_eval_plus_c_operator(), partial_eval_plus_or_minus_operator(), partial_eval_power_operator(), partial_eval_reference(), partial_eval_syntax(), partial_eval_unary_operator(), partial_eval_update_operators(), and regenerate_expression().
|
static |
when formating is useless (ie.
= (1 * expr + 0)) Set of enclosing loop indices
This set is maintained to avoid useless partial evaluation of loop indices which are very unlikely to be partially evaluable. Loops with only one iteration can be removed by dead code elimination.
This set is implemented as a list because the loop nest depth is expected small.
It would be nice to take inductive variables into account. Their evaluation is quite long in ocean. We could use the loop transformer instead of the loop index to populate live_loop_indices. But it would be harder to regenerate the set when leaving the loop, unless a copy is made on entrance.
A stack is not too attractive, as it should be all visited to make sure a variable is not a live loop index or inductive variable.
A multiset might make loop exit easier, but each membership test will be longer.
Definition at line 126 of file partial_eval.c.
Referenced by add_live_loop_index(), dump_live_loop_indices(), live_loop_index_p(), reset_live_loop_indices(), rm_live_loop_index(), and set_live_loop_indices().
|
static |
Definition at line 127 of file partial_eval.c.
Referenced by partial_eval_min_or_max_operator(), and partial_eval_statement().