PIPS
partial_eval.c File Reference
#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"
+ Include dependency graph for partial_eval.c:

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
 

Functions

void set_live_loop_indices ()
 cproto-generated files More...
 
void reset_live_loop_indices ()
 
void dump_live_loop_indices ()
 
static bool live_loop_index_p (entity i)
 
static void add_live_loop_index (entity i)
 
static void rm_live_loop_index (entity i)
 
void init_use_proper_effects (const char *module_name)
 
effects stmt_to_fx (statement stmt, statement_effects fx_map)
 returns proper effects associated to statement stmt More...
 
bool entity_written_p (entity ent, effects fx)
 
void init_use_preconditions (const char *module_name)
 
Psysteme stmt_prec (statement stmt)
 
void transformer_map_print (void)
 
bool eformat_equivalent_p (eformat_t ef1, eformat_t ef2)
 
void print_eformat (eformat_t ef, char *name)
 
void partial_eval_expression_and_regenerate (expression *ep, Psysteme ps, effects fx)
 
eformat_t partial_eval_expression_and_copy (expression expr, Psysteme ps, effects fx)
 
eformat_t partial_eval_expression (expression e, Psysteme ps, effects fx)
 
eformat_t partial_eval_syntax (expression e, Psysteme ps, effects fx)
 
eformat_t partial_eval_reference (expression e, Psysteme ps, effects fx)
 
void partial_eval_call_and_regenerate (call ca, Psysteme ps, effects fx)
 
eformat_t partial_eval_call (call ec, Psysteme ps, effects fx)
 
eformat_t partial_eval_call_expression (expression exp, Psysteme ps, effects fx)
 
eformat_t partial_eval_unary_operator (entity func, cons *la, Psysteme ps, effects fx)
 
eformat_t partial_eval_mult_operator (expression *ep1, expression *ep2, Psysteme ps, effects fx)
 
eformat_t partial_eval_plus_or_minus_operator (int token, expression *ep1, expression *ep2, Psysteme ps, effects fx)
 
eformat_t partial_eval_plus_operator (expression *ep1, expression *ep2, Psysteme ps, effects fx)
 
eformat_t partial_eval_plus_c_operator (expression *ep1, expression *ep2, Psysteme ps, effects fx)
 
eformat_t partial_eval_minus_operator (expression *ep1, expression *ep2, Psysteme ps, effects fx)
 
eformat_t partial_eval_minus_c_operator (expression *ep1, expression *ep2, Psysteme ps, effects fx)
 
eformat_t partial_eval_div_or_mod_operator (int token, expression *ep1, expression *ep2, Psysteme ps, effects fx)
 
eformat_t partial_eval_div_operator (expression *ep1, expression *ep2, Psysteme ps, effects fx)
 
eformat_t partial_eval_mod_operator (expression *ep1, expression *ep2, Psysteme ps, effects fx)
 
eformat_t partial_eval_c_mod_operator (expression *ep1, expression *ep2, Psysteme ps, effects fx)
 
eformat_t partial_eval_min_or_max_operator (int token, expression *ep1, expression *ep2, Psysteme ps, effects fx)
 
eformat_t partial_eval_min_operator (expression *ep1, expression *ep2, Psysteme ps, effects fx)
 
eformat_t partial_eval_max_operator (expression *ep1, expression *ep2, Psysteme ps, effects fx)
 
eformat_t partial_eval_power_operator (expression *ep1, expression *ep2, Psysteme ps, effects fx)
 
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. More...
 
eformat_t partial_eval_binary_operator (entity func, cons *la, Psysteme ps, effects fx)
 
eformat_t partial_eval_binary_operator_old (entity func, cons *la, Psysteme ps, effects fx)
 
void regenerate_expression (eformat_t *efp, expression *ep)
 in order to regenerate expression from eformat. More...
 
void regenerate_call (eformat_t *efp, call ca)
 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... More...
 
expression generate_monome (int coef, expression expr)
 
void partial_eval_declaration (entity v, Psysteme pre_sc, effects fx)
 assumes conditions checked by partial_eval_declarations() More...
 
void partial_eval_declarations (list el, Psysteme pre_sc, effects fx)
 
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 More...
 
bool partial_eval (const char *module_name)
 Top-level function. More...
 

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 []
 

Macro Definition Documentation

◆ PERFORM_ADDITION

#define PERFORM_ADDITION   1

Definition at line 716 of file partial_eval.c.

◆ PERFORM_C_DIVISION

#define PERFORM_C_DIVISION   14

Definition at line 720 of file partial_eval.c.

◆ PERFORM_C_MODULO

#define PERFORM_C_MODULO   16

Definition at line 723 of file partial_eval.c.

◆ PERFORM_DIVISION

#define PERFORM_DIVISION   4

Definition at line 719 of file partial_eval.c.

◆ PERFORM_MAXIMUM

#define PERFORM_MAXIMUM   8

Definition at line 725 of file partial_eval.c.

◆ PERFORM_MINIMUM

#define PERFORM_MINIMUM   7

Definition at line 724 of file partial_eval.c.

◆ PERFORM_MODULO

#define PERFORM_MODULO   6

Definition at line 722 of file partial_eval.c.

◆ PERFORM_MULTIPLICATION

#define PERFORM_MULTIPLICATION   3

Definition at line 718 of file partial_eval.c.

◆ PERFORM_POWER

#define PERFORM_POWER   5

Definition at line 721 of file partial_eval.c.

◆ PERFORM_SUBTRACTION

#define PERFORM_SUBTRACTION   2

Definition at line 717 of file partial_eval.c.

Function Documentation

◆ add_live_loop_index()

static void add_live_loop_index ( entity  i)
static

Definition at line 157 of file partial_eval.c.

158 {
159  pips_assert("add_live_index",!live_loop_index_p(i));
161  CONS(ENTITY, i, NIL));
162 }
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
static bool live_loop_index_p(entity i)
Definition: partial_eval.c:151
static list live_loop_indices
when formating is useless (ie.
Definition: partial_eval.c:126
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755

References CONS, ENTITY, gen_nconc(), live_loop_index_p(), live_loop_indices, NIL, and pips_assert.

Referenced by partial_eval_statement().

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

◆ dump_live_loop_indices()

void dump_live_loop_indices ( void  )

Definition at line 145 of file partial_eval.c.

146 {
147  pips_assert("set_live_loop_indices", live_loop_indices!=list_undefined);
149 }
void dump_arguments(cons *args)
entity_name is a macro, hence the code replication
Definition: arguments.c:69
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69

References dump_arguments(), list_undefined, live_loop_indices, and pips_assert.

+ Here is the call graph for this function:

◆ eformat_equivalent_p()

bool eformat_equivalent_p ( eformat_t  ef1,
eformat_t  ef2 
)

should not require anything about expr

ie expression_eq(ef1.expr, ef2.expr)

Parameters
ef1f1
ef2f2

Definition at line 269 of file partial_eval.c.

270 {
271  /* should not require anything about expr */
272  return( ef1.expr == ef2.expr /* ie expression_eq(ef1.expr, ef2.expr) */
273  && ef1.icoef == ef2.icoef
274  && ef1.ishift == ef2.ishift );
275 }
expression expr

References eformat::expr, eformat::icoef, and eformat::ishift.

Referenced by partial_eval_expression_and_copy(), and regenerate_expression().

+ Here is the caller graph for this function:

◆ entity_written_p()

bool entity_written_p ( entity  ent,
effects  fx 
)
Parameters
entnt
fxx

Definition at line 198 of file partial_eval.c.

199 {
200  if(fx==effects_undefined)
201  pips_internal_error("effects undefined");
202 
203  MAPL(ftl, {
204  effect ft = EFFECT(CAR(ftl));
209  return(true);
210  }, effects_effects(fx));
211 
212  return(false);
213 }
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
action_kind effect_action_kind(effect)
Definition: effects.c:1055
#define effects_undefined
Definition: effects.h:688
#define action_kind_store_p(x)
Definition: effects.h:259
#define effect_action(x)
Definition: effects.h:642
#define action_write_p(x)
Definition: effects.h:314
#define effects_effects(x)
Definition: effects.h:710
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define MAPL(_map_list_cp, _code, _l)
Apply some code on the addresses of all the elements of a list.
Definition: newgen_list.h:203
#define pips_internal_error
Definition: misc-local.h:149
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
#define reference_variable(x)
Definition: ri.h:2326
#define reference_indices(x)
Definition: ri.h:2328

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().

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

◆ generate_monome()

expression generate_monome ( int  coef,
expression  expr 
)
Parameters
coefoef
exprxpr

Definition at line 1623 of file partial_eval.c.

1624 {
1625  if(coef==0) {
1626  pips_assert("generate_monome", expr==expression_undefined);
1627  return(int_to_expression(0));
1628  }
1629  pips_assert("generate_monome", expr!=expression_undefined);
1630  if(coef==1) {
1631  return(expr);
1632  }
1633  if(coef==-1) {
1635  expr));
1636  }
1638  int_to_expression(coef),
1639  expr));
1640 }
#define UNARY_MINUS_OPERATOR_NAME
#define MULTIPLY_OPERATOR_NAME
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188
expression MakeUnaryCall(entity f, expression a)
Creates a call expression to a function with one argument.
Definition: expression.c:342
#define expression_undefined
Definition: ri.h:1223

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().

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

◆ init_use_preconditions()

void init_use_preconditions ( const char *  module_name)
Parameters
module_nameodule_name

Definition at line 216 of file partial_eval.c.

217 {
219  db_get_memory_resource(DBR_PRECONDITIONS, module_name, true) );
220  pips_assert("init_use_preconditions",
222  if(get_debug_level()==9) {
224  }
225 }
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
Definition: database.c:755
int get_debug_level(void)
GET_DEBUG_LEVEL returns the current debugging level.
Definition: debug.c:67
#define hash_table_undefined
Value of an undefined hash_table.
Definition: newgen_hash.h:49
void transformer_map_print(void)
Definition: partial_eval.c:252
void set_precondition_map(statement_mapping)
statement_mapping get_precondition_map(void)

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().

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

◆ init_use_proper_effects()

void init_use_proper_effects ( const char *  module_name)
Parameters
module_nameodule_name

Definition at line 171 of file partial_eval.c.

172 {
174  db_get_memory_resource(DBR_PROPER_EFFECTS, module_name, true));
175  pips_assert("init_use_proper_effects", !proper_rw_effects_undefined_p());
176 }
bool proper_rw_effects_undefined_p(void)
void set_proper_rw_effects(statement_effects)

References db_get_memory_resource(), module_name(), pips_assert, proper_rw_effects_undefined_p(), and set_proper_rw_effects().

Referenced by partial_eval().

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

◆ live_loop_index_p()

static bool live_loop_index_p ( entity  i)
static

Definition at line 151 of file partial_eval.c.

152 {
153  pips_assert("set_live_loop_indices", live_loop_indices!=list_undefined);
155 }
bool entity_is_argument_p(entity e, cons *args)
Definition: arguments.c:150

References entity_is_argument_p(), list_undefined, live_loop_indices, and pips_assert.

Referenced by add_live_loop_index(), and partial_eval_reference().

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

◆ partial_eval()

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.

Parameters
module_nameodule_name

Definition at line 1832 of file partial_eval.c.

1833 {
1834  entity module;
1836 
1837  /* be carrefull not to get any mapping before the code */
1838  /* DBR_CODE will be changed: argument "pure" is true because
1839  partial_eval() *modifies* DBR_CODE. */
1840  /* still bugs in dbm because effects are stored on disc after this phase */
1841 
1844 
1846  (statement) db_get_memory_resource(DBR_CODE, module_name, true));
1847 
1850 
1851  init_use_proper_effects(module_name); /* uses set_proper_effects_map */
1852 
1853  /* preconditions may need to print preconditions for debugging purposes */
1855  db_get_memory_resource(DBR_CUMULATED_EFFECTS, module_name, true));
1856 
1858 
1860 
1862 
1863  debug_on("PARTIAL_EVAL_DEBUG_LEVEL");
1866  debug_off();
1867 
1868  /* Reorder the module, because new statements may have been generated. */
1870 
1872 
1881 
1882  return true;
1883 }
static statement module_statement
Definition: alias_check.c:125
void reset_proper_rw_effects(void)
void set_cumulated_rw_effects(statement_effects)
void reset_cumulated_rw_effects(void)
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
#define DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
Definition: pipsdbm-local.h:66
#define debug_on(env)
Definition: misc-local.h:157
#define debug_off()
Definition: misc-local.h:160
void init_use_preconditions(const char *module_name)
Definition: partial_eval.c:216
void partial_eval_statement(statement stmt)
apply partial eval on each statement we cannot recurse on something other than a statement because we...
void init_use_proper_effects(const char *module_name)
Definition: partial_eval.c:171
void reset_live_loop_indices()
Definition: partial_eval.c:135
void set_live_loop_indices()
cproto-generated files
Definition: partial_eval.c:129
static char * module
Definition: pips.c:74
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
entity local_name_to_top_level_entity(const char *n)
This function try to find a top-level entity from a local name.
Definition: entity.c:1450
void free_statement_global_stack(void)
Definition: static.c:358
void make_statement_global_stack(void)
Definition: static.c:318
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
void module_to_value_mappings(entity m)
void module_to_value_mappings(entity m): build hash tables between variables and values (old,...
Definition: mappings.c:624
void reset_precondition_map(void)
void free_value_mappings(void)
Normal call to free the mappings.
Definition: value.c:1212

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.

+ Here is the call graph for this function:

◆ partial_eval_binary_operator()

eformat_t partial_eval_binary_operator ( entity  func,
cons la,
Psysteme  ps,
effects  fx 
)

some more optimization if a neutral element has been generated

se some partial eval dark magic

se some partial eval dark magic

Parameters
funcunc
laa
pss
fxx

Definition at line 1248 of file partial_eval.c.

1252 {
1253  eformat_t ef;
1254  expression *ep1, *ep2;
1255  int i = 0;
1256  eformat_t (*binary_partial_eval_operator)(expression *,
1257  expression *,
1258  Psysteme,
1259  effects) = 0;
1260 
1261  pips_assert("partial_eval_binary_operator", gen_length(la)==2);
1262  ep1= (expression*) REFCAR(la);
1263  ep2= (expression*) REFCAR(CDR(la));
1264 
1265  while (binary_operator_switch[i].operator_name!=NULL) {
1266  if (strcmp(binary_operator_switch[i].operator_name,
1267  entity_local_name(func))==0) {
1268  binary_partial_eval_operator =
1270  break;
1271  }
1272  i++;
1273  }
1274 
1275  if (binary_partial_eval_operator!=0)
1276  ef = binary_partial_eval_operator (ep1, ep2, ps, fx);
1277  else {
1280  ef = eformat_undefined;
1281  }
1282  /* some more optimization if a neutral element has been generated */
1283  entity neutral = operator_neutral_element(func);
1284  if(!entity_undefined_p(neutral)) {
1285  if(same_entity_p(expression_to_entity(*ep1),neutral)) {
1286  ef=partial_eval_expression(*ep2,ps,fx);
1287  if(!ef.simpler) /*use some partial eval dark magic */
1288  {
1289  ef.simpler=true;
1290  ef.icoef=1;
1291  ef.expr=*ep2;
1292  }
1293  }
1294  else if(same_entity_p(expression_to_entity(*ep2),neutral)) {
1295  ef=partial_eval_expression(*ep1,ps,fx);
1296  if(!ef.simpler) /*use some partial eval dark magic */
1297  {
1298  ef.simpler=true;
1299  ef.icoef=1;
1300  ef.expr=*ep1;
1301  }
1302  }
1303  }
1304 
1305  return ef;
1306 }
struct _newgen_struct_effects_ * effects
Definition: effects.h:138
struct eformat eformat_t
#define REFCAR(pc)
Get the adress of the first element of a list.
Definition: newgen_list.h:119
size_t gen_length(const list l)
Definition: list.c:150
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
eformat_t partial_eval_expression(expression e, Psysteme ps, effects fx)
Definition: partial_eval.c:318
static struct perform_switch binary_operator_switch[]
void partial_eval_expression_and_regenerate(expression *ep, Psysteme ps, effects fx)
Definition: partial_eval.c:284
static eformat_t eformat_undefined
Hypotheses pour l'implementation:
Definition: partial_eval.c:102
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
entity operator_neutral_element(entity op)
Definition: entity.c:2593
entity expression_to_entity(expression e)
just returns the entity of an expression, or entity_undefined
Definition: expression.c:3140
#define entity_undefined_p(x)
Definition: ri.h:2762
struct Ssysteme * Psysteme
eformat_t(* binary_operator)(expression *, expression *, Psysteme, effects)

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().

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

◆ partial_eval_binary_operator_old()

eformat_t partial_eval_binary_operator_old ( entity  func,
cons la,
Psysteme  ps,
effects  fx 
)

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

Parameters
funcunc
laa
pss
fxx

Definition at line 1308 of file partial_eval.c.

1312 {
1313  eformat_t ef, ef1, ef2;
1314  expression *ep1, *ep2;
1315  int token= -1;
1316 
1317  pips_assert("partial_eval_binary_operator", gen_length(la)==2);
1318  ep1= (expression*) REFCAR(la);
1319  ep2= (expression*) REFCAR(CDR(la));
1320 
1321  if (strcmp(entity_local_name(func), MINUS_OPERATOR_NAME) == 0) {
1322  token = PERFORM_SUBTRACTION;
1323  }
1324  else if (strcmp(entity_local_name(func), PLUS_OPERATOR_NAME) == 0) {
1325  token = PERFORM_ADDITION;
1326  }
1327  else if (strcmp(entity_local_name(func), MULTIPLY_OPERATOR_NAME) == 0) {
1328  token = PERFORM_MULTIPLICATION;
1329  }
1330  else if (strcmp(entity_local_name(func), DIVIDE_OPERATOR_NAME) == 0) {
1331  /* FI: The C divide operator may be defined differently for negative
1332  integers */
1333  token = PERFORM_DIVISION;
1334  }
1335  else if (strcmp(entity_local_name(func), MODULO_OPERATOR_NAME) == 0) {
1336  token = PERFORM_MODULO;
1337  }
1338  else if (strcmp(entity_local_name(func), C_MODULO_OPERATOR_NAME) == 0) {
1339  /* FI: The C modulo operator may be defined differently for negative
1340  integers */
1341  token = PERFORM_MODULO;
1342  }
1343 
1344  if ( token==PERFORM_ADDITION || token==PERFORM_SUBTRACTION ) {
1345  ef1 = partial_eval_expression_and_copy(*ep1, ps, fx);
1346  ef2 = partial_eval_expression_and_copy(*ep2, ps, fx);
1347 
1348  /* generate ef.icoef and ef.expr */
1349  if( (ef1.icoef==ef2.icoef || ef1.icoef==-ef2.icoef)
1350  && (ef1.icoef<-1 || ef1.icoef>1) ) {
1351  /* factorize */
1352  ef.simpler=true;
1353  if( (token==PERFORM_ADDITION && ef1.icoef==ef2.icoef)
1354  || (token==PERFORM_SUBTRACTION && ef1.icoef==-ef2.icoef) ) {
1355  /* addition */
1357  ef1.expr,
1358  ef2.expr);
1359  ef.icoef= ef1.icoef;
1360  }
1361  else if( (ef1.icoef>1)
1362  && (token==PERFORM_SUBTRACTION ? (ef2.icoef>0) : (ef2.icoef<0)) ) {
1363  /* substraction e1-e2 */
1365  ef1.expr,
1366  ef2.expr);
1367  ef.icoef= ef1.icoef;
1368  }
1369  else {
1370  /* substraction e2-e1 */
1372  ef2.expr,
1373  ef1.expr);
1374  ef.icoef= -ef1.icoef;
1375  }
1376  }
1377  else if(ef1.icoef!=0 && ef2.icoef!=0) {
1378  int c1 = ef1.icoef;
1379  int c2 = (token==PERFORM_SUBTRACTION ? -ef2.icoef : ef2.icoef);
1380  expression e1= generate_monome((c1>0 ? c1: -c1), ef1.expr);
1381  expression e2= generate_monome((c2>0 ? c2: -c2), ef2.expr);
1382  /* generate without factorize */
1383  ef.simpler= (ef1.simpler || ef2.simpler); /* not precise ?? */
1384  if(c1*c2>0) {
1386  e1, e2);
1387  ef.icoef= (c1>0 ? 1 : -1);
1388  }
1389  else if(c1>0) {
1391  e1, e2);
1392  ef.icoef= 1;
1393  }
1394  else {
1396  e2, e1);
1397  ef.icoef= 1;
1398  }
1399  }
1400  else {
1401  ef.simpler= (ef1.simpler || ef2.simpler);
1402  if(ef1.icoef==0) {
1403  if(ef1.ishift==0) ef.simpler=true;
1404  ef.expr=ef2.expr;
1405  ef.icoef=(token==PERFORM_SUBTRACTION ? -ef2.icoef : ef2.icoef);
1406  }
1407  else {
1408  if(ef2.ishift==0) ef.simpler=true;
1409  ef.expr=ef1.expr;
1410  ef.icoef=ef1.icoef;
1411  }
1412  }
1413 
1414  /* generate ef.ishift */
1415  if ( (ef1.icoef==0 || ef1.ishift!=0)
1416  && (ef2.icoef==0 || ef2.ishift!=0) ) {
1417  /* simplify shifts */
1418  ef.simpler= true;
1419  }
1420  ef.ishift= (token==PERFORM_SUBTRACTION ?
1421  ef1.ishift-ef2.ishift : ef1.ishift+ef2.ishift);
1422  }
1423  else if( token==PERFORM_MULTIPLICATION ) {
1424  ef1 = partial_eval_expression_and_copy(*ep1, ps, fx);
1425  ef2 = partial_eval_expression_and_copy(*ep2, ps, fx);
1426 
1427  if(ef1.icoef==0 && ef2.icoef==0) {
1428  ef.icoef=0;
1430  ef.ishift= ef1.ishift * ef2.ishift;
1431  ef.simpler= true;
1432  }
1433  else if(ef1.icoef!=0 && ef2.icoef!=0) {
1434  if(ef2.icoef!=1 && ef2.ishift==0) {
1435  expression *ep;
1436  /* exchange ef1 and ef2 (see later) */
1437  ef=ef2; ef2=ef1; ef1=ef; ef= eformat_undefined;
1438  ep=ep2; ep2=ep1; ep1=ep;
1439  }
1440  if(ef1.icoef!=1 && ef1.ishift==0) {
1441  ef.simpler= ef1.simpler;
1442  ef.icoef= ef1.icoef;
1443  regenerate_expression(&ef2, ep2);
1445  ef1.expr, *ep2);
1446  ef.ishift= 0;
1447  }
1448  else { /* cannot optimize */
1449  regenerate_expression(&ef1, ep1);
1450  regenerate_expression(&ef2, ep2);
1451 
1452  ef= eformat_undefined;
1453  }
1454  }
1455  else {
1456  if(ef2.icoef==0) {
1457  expression *ep;
1458  /* exchange ef1 and ef2 (see later) */
1459  ef=ef2; ef2=ef1; ef1=ef; ef= eformat_undefined;
1460  ep=ep2; ep2=ep1; ep1=ep;
1461  }
1462  /* here we know that ef1.ecoef==0 and ef2.ecoef!=0 */
1463  if(ef1.ishift==0) {
1464  ef.icoef= 0;
1466  ef.ishift= 0;
1467  ef.simpler= true;
1468  regenerate_expression(&ef2, ep2);
1469  }
1470  else {
1471  ef.icoef= ef1.ishift * ef2.icoef;
1472  ef.expr= ef2.expr;
1473  ef.ishift= ef1.ishift * ef2.ishift;
1474  ef.simpler= (ef1.ishift==1 || ef2.icoef!=1
1475  || ef1.simpler || ef2.simpler);
1476  }
1477  }
1478  }
1479  else if(token==PERFORM_DIVISION || token==PERFORM_MODULO) {
1480  ef1 = partial_eval_expression_and_copy(*ep1, ps, fx);
1481  ef2 = partial_eval_expression_and_copy(*ep2, ps, fx);
1482 
1483  if( ef2.icoef==0 && ef2.ishift == 0 )
1484  user_error("partial_eval_binary_operator",
1485  "division by zero!\n");
1486  if( token==PERFORM_DIVISION && ef2.icoef==0
1487  && (ef1.ishift % ef2.ishift)==0
1488  && (ef1.icoef % ef2.ishift)==0 ) {
1489  /* integer division does NOT commute with in any */
1490  /* multiplication -> only performed if "exact" */
1491  ef.simpler= true;
1492  ef.icoef= ef1.icoef / ef2.ishift;
1493  ef.ishift= ef1.ishift / ef2.ishift;
1494  ef.expr= ef1.expr;
1495  }
1496  else if(ef1.icoef==0 && ef2.icoef==0) {
1497  ef.simpler= true;
1498  ef.icoef= 0;
1500  if (token==PERFORM_DIVISION) { /* refer to Fortran77 chap 6.1.5 */
1501  ef.ishift= FORTRAN_DIV(ef1.ishift, ef2.ishift);
1502  }
1503  else { /* tocken==PERFORM_MODULO */
1504  ef.ishift= FORTRAN_MOD(ef1.ishift, ef2.ishift);
1505  }
1506  }
1507  else {
1508  regenerate_expression(&ef1, ep1);
1509  regenerate_expression(&ef2, ep2);
1510  ef= eformat_undefined;
1511  }
1512  }
1513  else {
1516  ef= eformat_undefined;
1517  }
1518  return(ef);
1519 }
#define FORTRAN_DIV(n, d)
Definition: misc-local.h:213
#define FORTRAN_MOD(n, m)
Definition: misc-local.h:215
#define user_error(fn,...)
Definition: misc-local.h:265
#define PERFORM_MULTIPLICATION
Definition: partial_eval.c:718
eformat_t partial_eval_expression_and_copy(expression expr, Psysteme ps, effects fx)
Definition: partial_eval.c:305
#define PERFORM_ADDITION
Definition: partial_eval.c:716
#define PERFORM_DIVISION
Definition: partial_eval.c:719
#define PERFORM_SUBTRACTION
Definition: partial_eval.c:717
#define PERFORM_MODULO
Definition: partial_eval.c:722
expression generate_monome(int coef, expression expr)
void regenerate_expression(eformat_t *efp, expression *ep)
in order to regenerate expression from eformat.
#define C_MODULO_OPERATOR_NAME
#define MINUS_OPERATOR_NAME
#define PLUS_OPERATOR_NAME
#define DIVIDE_OPERATOR_NAME
#define MODULO_OPERATOR_NAME

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.

+ Here is the call graph for this function:

◆ partial_eval_c_mod_operator()

eformat_t partial_eval_c_mod_operator ( expression ep1,
expression ep2,
Psysteme  ps,
effects  fx 
)
Parameters
ep1p1
ep2p2
pss
fxx

Definition at line 1079 of file partial_eval.c.

1083 {
1084  eformat_t ef;
1085 
1087  ep1, ep2, ps, fx);
1088 
1089  return ef;
1090 }
eformat_t partial_eval_div_or_mod_operator(int token, expression *ep1, expression *ep2, Psysteme ps, effects fx)
Definition: partial_eval.c:993
#define PERFORM_C_MODULO
Definition: partial_eval.c:723

References partial_eval_div_or_mod_operator(), and PERFORM_C_MODULO.

+ Here is the call graph for this function:

◆ partial_eval_call()

eformat_t partial_eval_call ( call  ec,
Psysteme  ps,
effects  fx 
)

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

Parameters
ecc
pss
fxx

Definition at line 574 of file partial_eval.c.

575 {
576  entity func;
577  value vinit;
578  eformat_t ef;
579  func = call_function(ec);
580  vinit = entity_initial(func);
581 
582  switch (value_tag(vinit)) {
583  case is_value_intrinsic:
584  case is_value_unknown: {
585  /* it might be an intrinsic function */
586  cons *la = call_arguments(ec);
587  size_t nbargs = gen_length(la);
588  switch(nbargs) {
589  case 1:
590  ef = partial_eval_unary_operator(func, la, ps, fx);break;
591  case 2:
592  ef = partial_eval_binary_operator(func, la, ps, fx);break;
593  default:
594  {
596  ef = eformat_undefined;
597  }
598  }
599  } break;
600  case is_value_constant:
601  if(integer_constant_p(func, &ef.ishift)) {
602  ef.icoef = 0;
604  ef.simpler = false;
605  }
606  else ef = eformat_undefined;
607  break;
608  case is_value_symbolic:
609  if(integer_symbolic_constant_p(func, &ef.ishift)) {
610  ef.icoef = 0;
612  ef.simpler = true;
613  }
614  else ef = eformat_undefined;
615  break;
616  case is_value_code:
617  {
618  /* FI: The actual aruments are not partially evaluated?
619  * SG: no it's not, I fixed this
620  *
621  * FI: Actually, the parameter mode should be checked. And the
622  * actual effects.
623  *
624  * Note FI: the result obtained for the call to fx in
625  * Transformations/eval.c is correct, but I do not understand
626  * why. Actual parameters must be evaluated somewhere else.
627  */
628  list ce;
629  for(ce = call_arguments(ec); !ENDP(ce); POP(ce))
630  {
631  expression eparam = EXPRESSION(CAR(ce));
632  if(c_language_module_p(func)) {
633  /* value passing */
635  EXPRESSION_(CAR(ce)) = eparam;
636  }
637  else if(fortran_language_module_p(func)) {
638  /* the partial evaluation could be further improved by
639  checking if there is a write effect on the
640  corresponding formal parameter */
641  if(false && expression_reference_p(eparam))
642  /* This is dealt for using fx when dealing with a
643  reference */
644  ; // in doubt, do nothing
645  else {
647  EXPRESSION_(CAR(ce)) = eparam;
648  }
649  }
650  else {
651  pips_internal_error("Unexpected programming language");
652  }
653  }
654 
655  ef = eformat_undefined;
656  } break;
657  default:
658  pips_internal_error("Default case reached.");
659  ef = eformat_undefined;
660  }
661  return ef;
662 }
bool integer_constant_p(entity ent, int *int_p)
Returns the double value associated to a PIPS constant.
Definition: constant.c:542
bool integer_symbolic_constant_p(entity ent, int *int_p)
(*int_p) gets integer constant if any
Definition: constant.c:556
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
eformat_t partial_eval_unary_operator(entity func, cons *la, Psysteme ps, effects fx)
Definition: partial_eval.c:680
eformat_t partial_eval_binary_operator(entity func, cons *la, Psysteme ps, effects fx)
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
bool c_language_module_p(entity m)
Definition: module.c:447
bool fortran_language_module_p(entity m)
Definition: module.c:452
#define value_tag(x)
Definition: ri.h:3064
#define call_function(x)
Definition: ri.h:709
#define EXPRESSION_(x)
Definition: ri.h:1220
@ is_value_intrinsic
Definition: ri.h:3034
@ is_value_unknown
Definition: ri.h:3035
@ is_value_constant
Definition: ri.h:3033
@ is_value_code
Definition: ri.h:3031
@ is_value_symbolic
Definition: ri.h:3032
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define call_arguments(x)
Definition: ri.h:711
#define entity_initial(x)
Definition: ri.h:2796
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

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().

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

◆ partial_eval_call_and_regenerate()

void partial_eval_call_and_regenerate ( call  ca,
Psysteme  ps,
effects  fx 
)

FI: if the call is an operator, it is not part of the simplification; e.g. "3+5;"

Parameters
caa
pss
fxx

Definition at line 553 of file partial_eval.c.

554 {
555  //list le = list_undefined;
556  eformat_t ef = partial_eval_call(ca, ps, fx);
557 
558  pips_assert("ca is a defined call", ca!= call_undefined);
559 
560  /* FI: if the call is an operator, it is not part of the
561  simplification; e.g. "3+5;" */
562  /*
563  for(le=call_arguments(ca); !ENDP(le); POP(le)) {
564  expression exp = EXPRESSION(CAR(le));
565 
566  partial_eval_expression_and_regenerate(&exp, ps, fx);
567  EXPRESSION_(CAR(le))= exp;
568  }
569  */
570  regenerate_call(&ef, ca);
571 }
void regenerate_call(eformat_t *efp, call ca)
We are likely to end up in trouble because the regenerated expression may not be a call; for instance...
eformat_t partial_eval_call(call ec, Psysteme ps, effects fx)
Definition: partial_eval.c:574
#define call_undefined
Definition: ri.h:685

References call_undefined, partial_eval_call(), pips_assert, and regenerate_call().

Referenced by partial_eval_statement().

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

◆ partial_eval_call_expression()

eformat_t partial_eval_call_expression ( expression  exp,
Psysteme  ps,
effects  fx 
)
Parameters
expxp
pss
fxx

Definition at line 664 of file partial_eval.c.

665 {
666  call ec;
667  //entity func;
668  //value vinit;
669  eformat_t ef;
670 
671  pips_assert("The expression is a call",
674 
675  ef = partial_eval_call(ec, ps,fx);
676 
677  return ef;
678 }
#define syntax_call_p(x)
Definition: ri.h:2734
#define syntax_call(x)
Definition: ri.h:2736
#define expression_syntax(x)
Definition: ri.h:1247
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207

References exp, expression_syntax, partial_eval_call(), pips_assert, syntax_call, and syntax_call_p.

Referenced by partial_eval_syntax().

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

◆ partial_eval_declaration()

void partial_eval_declaration ( entity  v,
Psysteme  pre_sc,
effects  fx 
)

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

Parameters
pre_scre_sc
fxx

Definition at line 1648 of file partial_eval.c.

1649 {
1650  type vt = entity_type(v);
1653 
1654  /* See if the dimensions can be simplified */
1655  FOREACH(DIMENSION, d, dl) {
1658  }
1659 
1660  /* See if the initialization expression can be simplified */
1661  if(!expression_undefined_p(ie)) {
1662  /* FI: Lots of short cuts about side effects: pre and fx should be
1663  recomputed between each partial evaluation by the caller... */
1664  partial_eval_expression_and_regenerate(&ie, pre_sc, fx);
1666  /* Too bad for the memory leak of entity_initial() but I'm afraid
1667  the expression might be shared*/
1668  }
1669 }
value make_value_expression(expression _field_)
Definition: ri.c:2850
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
expression variable_initial_expression(entity)
Returns a copy of the initial (i.e.
Definition: variable.c:1899
#define dimension_lower(x)
Definition: ri.h:980
#define type_variable(x)
Definition: ri.h:2949
#define dimension_upper(x)
Definition: ri.h:982
#define expression_undefined_p(x)
Definition: ri.h:1224
#define variable_dimensions(x)
Definition: ri.h:3122
#define entity_type(x)
Definition: ri.h:2792

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().

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

◆ partial_eval_declarations()

void partial_eval_declarations ( list  el,
Psysteme  pre_sc,
effects  fx 
)
Parameters
ell
pre_scre_sc
fxx

Definition at line 1672 of file partial_eval.c.

1673 {
1674  FOREACH(ENTITY, e, el) {
1676  partial_eval_declaration(e, pre_sc, fx);
1677  }
1678 }
void partial_eval_declaration(entity v, Psysteme pre_sc, effects fx)
assumes conditions checked by partial_eval_declarations()
#define entity_variable_p(e)
An entity_variable_p(e) may hide a typedef and hence a functional type.
bool variable_entity_p(entity)
variable.c
Definition: variable.c:70

References ENTITY, entity_variable_p, FOREACH, partial_eval_declaration(), and variable_entity_p().

Referenced by partial_eval_statement().

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

◆ partial_eval_div_operator()

eformat_t partial_eval_div_operator ( expression ep1,
expression ep2,
Psysteme  ps,
effects  fx 
)
Parameters
ep1p1
ep2p2
pss
fxx

Definition at line 1053 of file partial_eval.c.

1057 {
1058  eformat_t ef;
1059 
1061  ep1, ep2, ps, fx);
1062 
1063  return ef;
1064 }

References partial_eval_div_or_mod_operator(), and PERFORM_DIVISION.

+ Here is the call graph for this function:

◆ partial_eval_div_or_mod_operator()

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.

Parameters
tokenoken
ep1p1
ep2p2
pss
fxx

Definition at line 993 of file partial_eval.c.

998 {
999  eformat_t ef, ef1, ef2;
1000 
1001  ef1 = partial_eval_expression_and_copy(*ep1, ps, fx);
1002  ef2 = partial_eval_expression_and_copy(*ep2, ps, fx);
1003 
1004  if( ef2.icoef==0 && ef2.ishift == 0 )
1005  user_error("partial_eval_div_or_mod_operator",
1006  "division by zero!\n");
1007  if( token==PERFORM_DIVISION && ef2.icoef==0
1008  && (ef1.ishift % ef2.ishift)==0
1009  && (ef1.icoef % ef2.ishift)==0 ) {
1010  /* integer division does NOT commute with in any */
1011  /* multiplication -> only performed if "exact" */
1012  ef.simpler= true;
1013  ef.icoef= ef1.icoef / ef2.ishift;
1014  ef.ishift= ef1.ishift / ef2.ishift;
1015  ef.expr= ef1.expr;
1016  }
1017  else if(ef1.icoef==0 && ef2.icoef==0) {
1018  ef.simpler= true;
1019  ef.icoef= 0;
1021  if (token==PERFORM_DIVISION) { /* refer to Fortran77 chap 6.1.5 */
1022  /* FI->SG: FORTRAN_DIV, SIGN_EQ, FORTRAN_MOD,... have been left in
1023  transformations-local.h when this code was moved into
1024  expressions. I haven't checked if they are used
1025  elsewhere. Could the expression library not dependent on
1026  transformations? */
1027  ef.ishift= FORTRAN_DIV(ef1.ishift, ef2.ishift);
1028  }
1029  else {
1030  /* FI: C and Fortran modulo and division operators seem in fact
1031  equivalent, using negative modulo to maintain the equation
1032 
1033  a == (a/b)*b+a%b
1034 
1035  instead of a positive remainder, i.e. modulo.
1036  */
1037  if(token==PERFORM_MODULO)
1038  ef.ishift= FORTRAN_MOD(ef1.ishift, ef2.ishift);
1039  else if(token==PERFORM_C_MODULO)
1040  ef.ishift= C_MODULO(ef1.ishift, ef2.ishift);
1041  else
1042  pips_internal_error("Unexpected tocken");
1043  }
1044  }
1045  else {
1046  regenerate_expression(&ef1, ep1);
1047  regenerate_expression(&ef2, ep2);
1048  ef= eformat_undefined;
1049  }
1050  return ef;
1051 }
#define C_MODULO(n, m)
Definition: misc-local.h:216

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().

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

◆ partial_eval_expression()

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()

Parameters
pss
fxx

Definition at line 318 of file partial_eval.c.

319 {
320  eformat_t ef;
321  expression ne = e;
322  normalized n;
323 
326  n = expression_normalized(e);
327 
328  /* In case the expression is affine, use its affine form
329 
330  FI: it would be better to test if ne is really simpler than e: it
331  should contain fewer operators (1+1->2) or fewer references
332  (n->1).
333  */
334  if(normalized_linear_p(n)) {
335  Pvecteur pv = normalized_linear(n);
336  ne = make_vecteur_expression(pv);
337  ef = partial_eval_syntax(ne, ps, fx);
338  if(!ef.simpler /*&& !ef.icoef==0 && !ef.ishift==0*/) {
339  /* FI: it may be simpler because the simplification may be
340  performed by normalize_expression() */
341  ef.simpler = true;
342  if(expression_undefined_p(ef.expr) && ef.icoef!=0)
343  ef.expr = ne;
344  //ef.expr = ne;
345  //ef.icoef = 1;
346  //ef.ishift = 0;
347  }
348  }
349  else
350  ef = partial_eval_syntax(ne, ps, fx);
351 
352  return ef;
353 }
eformat_t partial_eval_syntax(expression e, Psysteme ps, effects fx)
Definition: partial_eval.c:355
void unnormalize_expression(void *st)
void unnormalize_expression(expression exp): puts all the normalized field of expressions in "st" to ...
Definition: normalize.c:452
#define NORMALIZE_EXPRESSION(e)
expression make_vecteur_expression(Pvecteur pv)
make expression for vector (Pvecteur)
Definition: expression.c:1650
#define normalized_linear_p(x)
Definition: ri.h:1779
#define expression_normalized(x)
Definition: ri.h:1249
#define normalized_linear(x)
Definition: ri.h:1781
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89

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().

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

◆ partial_eval_expression_and_copy()

eformat_t partial_eval_expression_and_copy ( expression  expr,
Psysteme  ps,
effects  fx 
)
Parameters
exprxpr
pss
fxx

Definition at line 305 of file partial_eval.c.

306 {
307  eformat_t ef;
308 
309  ef = partial_eval_expression(expr, ps, fx);
310 
312  ef.expr = expr;
313  }
314 
315  return(ef);
316 }
bool eformat_equivalent_p(eformat_t ef1, eformat_t ef2)
Definition: partial_eval.c:269

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().

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

◆ partial_eval_expression_and_regenerate()

void partial_eval_expression_and_regenerate ( expression ep,
Psysteme  ps,
effects  fx 
)
Parameters
epp
pss
fxx

Definition at line 284 of file partial_eval.c.

285 {
286  eformat_t ef;
287 
288  ef = partial_eval_expression(*ep, ps, fx);
289 
290  ifdebug(5)
291  print_eformat(ef, "before regenerate");
292 
293  regenerate_expression(&ef, ep);
294 
295  ifdebug(5) {
296  if(!expression_consistent_p(*ep)) {
297  pips_internal_error("bad evaluation");
298  }
299  else {
300  print_eformat(ef, "after regenerate");
301  }
302  }
303 }
bool expression_consistent_p(expression p)
Definition: ri.c:859
void print_eformat(eformat_t ef, char *name)
Definition: partial_eval.c:277
#define ifdebug(n)
Definition: sg.c:47

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().

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

◆ partial_eval_max_operator()

eformat_t partial_eval_max_operator ( expression ep1,
expression ep2,
Psysteme  ps,
effects  fx 
)
Parameters
ep1p1
ep2p2
pss
fxx

Definition at line 1156 of file partial_eval.c.

1160 {
1161  eformat_t ef;
1162 
1164  ep1, ep2, ps, fx);
1165 
1166  return ef;
1167 }
#define PERFORM_MAXIMUM
Definition: partial_eval.c:725
eformat_t partial_eval_min_or_max_operator(int token, expression *ep1, expression *ep2, Psysteme ps, effects fx)

References partial_eval_min_or_max_operator(), and PERFORM_MAXIMUM.

+ Here is the call graph for this function:

◆ partial_eval_min_operator()

eformat_t partial_eval_min_operator ( expression ep1,
expression ep2,
Psysteme  ps,
effects  fx 
)
Parameters
ep1p1
ep2p2
pss
fxx

Definition at line 1143 of file partial_eval.c.

1147 {
1148  eformat_t ef;
1149 
1151  ep1, ep2, ps, fx);
1152 
1153  return ef;
1154 }
#define PERFORM_MINIMUM
Definition: partial_eval.c:724

References partial_eval_min_or_max_operator(), and PERFORM_MINIMUM.

+ Here is the call graph for this function:

◆ partial_eval_min_or_max_operator()

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

Parameters
tokenoken
ep1p1
ep2p2
pss
fxx

Definition at line 1092 of file partial_eval.c.

1097 {
1098  eformat_t ef;
1099  bool ok = false;
1100  {
1103  intptr_t lb,ub;
1104  if(precondition_minmax_of_expression(fake,tr,&lb,&ub))
1105  {
1106  if(lb>=0) /* ep1-ep2 >= 0 -> min(ep1,ep2) == ep2 and max(ep1,ep2) == ep1 */
1107  {
1108  ef= partial_eval_expression_and_copy(*(token==PERFORM_MAXIMUM?ep1:ep2),ps,fx);
1109  ef.simpler=true;
1110  ok=true;
1111  }
1112  else if(ub <= 0 ) /* ep1-ep2 <= 0 -> min(ep1,ep2) == ep1 and max(ep1,ep2) == ep2 */
1113  {
1114  ef= partial_eval_expression_and_copy(*(token==PERFORM_MAXIMUM?ep2:ep1),ps,fx);
1115  ef.simpler=true;
1116  ok=true;
1117  }
1118  }
1119  }
1120 
1121  if(!ok) {
1122  eformat_t ef1, ef2;
1123  ef1 = partial_eval_expression_and_copy(*ep1, ps, fx);
1124  ef2 = partial_eval_expression_and_copy(*ep2, ps, fx);
1125 
1126  if( ef1.icoef == 0 && ef2.icoef == 0 ) {
1127  ef.icoef = 0;
1128  ef.ishift = (token==PERFORM_MAXIMUM)? MAX(ef1.ishift,ef2.ishift):
1129  MIN(ef1.ishift,ef2.ishift);
1131  ef.simpler = true;
1132  }
1133  else {
1134  regenerate_expression(&ef1, ep1);
1135  regenerate_expression(&ef2, ep2);
1136  ef = eformat_undefined;
1137  }
1138  }
1139 
1140  return ef;
1141 }
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
#define MIN(x, y)
minimum and maximum if they are defined somewhere else, they are very likely to be defined the same w...
static statement partial_eval_current_statement
Definition: partial_eval.c:127
expression make_op_exp(char *op_name, expression exp1, expression exp2)
================================================================
Definition: expression.c:2012
bool precondition_minmax_of_expression(expression exp, transformer tr, intptr_t *pmin, intptr_t *pmax)
compute integer bounds pmax, pmin of expression exp under preconditions tr require value mappings set...
Definition: expression.c:5818
transformer load_statement_precondition(statement)
static bool ok
#define intptr_t
Definition: stdint.in.h:294
#define MAX(x, y)
Definition: string.c:110
transformer transformer_range(transformer tf)
Return the range of relation tf in a newly allocated transformer.
Definition: transformer.c:714

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().

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

◆ partial_eval_minus_c_operator()

eformat_t partial_eval_minus_c_operator ( expression ep1,
expression ep2,
Psysteme  ps,
effects  fx 
)
Parameters
ep1p1
ep2p2
pss
fxx

Definition at line 972 of file partial_eval.c.

976 {
978  basic b1 = basic_of_expression(*ep1);
979  basic b2 = basic_of_expression(*ep2);
980  if( !basic_pointer_p(b1) && !basic_pointer_p(b2) )
981  {
982  ef = partial_eval_minus_operator(ep1,ep2,ps,fx);
983  }
984  else {
987  }
988  free_basic(b1);
989  free_basic(b2);
990  return ef;
991 }
void free_basic(basic p)
Definition: ri.c:107
eformat_t partial_eval_minus_operator(expression *ep1, expression *ep2, Psysteme ps, effects fx)
Definition: partial_eval.c:959
basic basic_of_expression(expression)
basic basic_of_expression(expression exp): Makes a basic of the same basic as the expression "exp".
Definition: type.c:1383
#define basic_pointer_p(x)
Definition: ri.h:635
Value b2
Definition: sc_gram.c:105
Value b1
booleen indiquant quel membre est en cours d'analyse
Definition: sc_gram.c:105

References b1, b2, basic_of_expression(), basic_pointer_p, eformat_undefined, free_basic(), partial_eval_expression_and_regenerate(), and partial_eval_minus_operator().

+ Here is the call graph for this function:

◆ partial_eval_minus_operator()

eformat_t partial_eval_minus_operator ( expression ep1,
expression ep2,
Psysteme  ps,
effects  fx 
)
Parameters
ep1p1
ep2p2
pss
fxx

Definition at line 959 of file partial_eval.c.

963 {
964  eformat_t ef;
965 
967  ep1, ep2, ps, fx);
968 
969  return ef;
970 }
eformat_t partial_eval_plus_or_minus_operator(int token, expression *ep1, expression *ep2, Psysteme ps, effects fx)
Definition: partial_eval.c:792

References partial_eval_plus_or_minus_operator(), and PERFORM_SUBTRACTION.

Referenced by partial_eval_minus_c_operator().

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

◆ partial_eval_mod_operator()

eformat_t partial_eval_mod_operator ( expression ep1,
expression ep2,
Psysteme  ps,
effects  fx 
)
Parameters
ep1p1
ep2p2
pss
fxx

Definition at line 1066 of file partial_eval.c.

1070 {
1071  eformat_t ef;
1072 
1074  ep1, ep2, ps, fx);
1075 
1076  return ef;
1077 }

References partial_eval_div_or_mod_operator(), and PERFORM_MODULO.

+ Here is the call graph for this function:

◆ partial_eval_mult_operator()

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

Parameters
ep1p1
ep2p2
pss
fxx

Definition at line 727 of file partial_eval.c.

731 {
732  eformat_t ef, ef1, ef2;
733 
734  ef1 = partial_eval_expression_and_copy(*ep1, ps, fx);
735  ef2 = partial_eval_expression_and_copy(*ep2, ps, fx);
736 
737  if(ef1.icoef==0 && ef2.icoef==0) {
738  ef.icoef=0;
740  ef.ishift= ef1.ishift * ef2.ishift;
741  ef.simpler= true;
742  }
743  else if(ef1.icoef!=0 && ef2.icoef!=0) {
744  if(ef2.icoef!=1 && ef2.ishift==0) {
745  expression *ep;
746  /* exchange ef1 and ef2 (see later) */
747  ef=ef2; ef2=ef1; ef1=ef; ef= eformat_undefined;
748  ep=ep2; ep2=ep1; ep1=ep;
749  }
750  if(ef1.icoef!=1 && ef1.ishift==0) {
751  ef.simpler= ef1.simpler;
752  ef.icoef= ef1.icoef;
753  regenerate_expression(&ef2, ep2);
755  ef1.expr, *ep2);
756  ef.ishift= 0;
757  }
758  else { /* cannot optimize */
759  regenerate_expression(&ef1, ep1);
760  regenerate_expression(&ef2, ep2);
761 
762  ef= eformat_undefined;
763  }
764  }
765  else {
766  if(ef2.icoef==0) {
767  expression *ep;
768  /* exchange ef1 and ef2 (see later) */
769  ef=ef2; ef2=ef1; ef1=ef; ef= eformat_undefined;
770  ep=ep2; ep2=ep1; ep1=ep;
771  }
772  /* here we know that ef1.ecoef==0 and ef2.ecoef!=0 */
773  if(ef1.ishift==0) {
774  ef.icoef= 0;
776  ef.ishift= 0;
777  ef.simpler= true;
778  regenerate_expression(&ef2, ep2);
779  }
780  else {
781  ef.icoef= ef1.ishift * ef2.icoef;
782  ef.expr= ef2.expr;
783  ef.ishift= ef1.ishift * ef2.ishift;
784  ef.simpler= (ef1.ishift==1 || ef2.icoef!=1
785  || ef1.simpler || ef2.simpler);
786  }
787  }
788 
789  return ef;
790 }

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.

+ Here is the call graph for this function:

◆ partial_eval_plus_c_operator()

eformat_t partial_eval_plus_c_operator ( expression ep1,
expression ep2,
Psysteme  ps,
effects  fx 
)
Parameters
ep1p1
ep2p2
pss
fxx

Definition at line 937 of file partial_eval.c.

941 {
943  basic b1 = basic_of_expression(*ep1);
944  basic b2 = basic_of_expression(*ep2);
945  if( !basic_pointer_p(b1) && !basic_pointer_p(b2) )
946  {
947  ef = partial_eval_plus_operator(ep1,ep2,ps,fx);
948  }
949  else {
952  }
953  free_basic(b1);
954  free_basic(b2);
955 
956  return ef;
957 }
eformat_t partial_eval_plus_operator(expression *ep1, expression *ep2, Psysteme ps, effects fx)
Definition: partial_eval.c:924

References b1, b2, basic_of_expression(), basic_pointer_p, eformat_undefined, free_basic(), partial_eval_expression_and_regenerate(), and partial_eval_plus_operator().

+ Here is the call graph for this function:

◆ partial_eval_plus_operator()

eformat_t partial_eval_plus_operator ( expression ep1,
expression ep2,
Psysteme  ps,
effects  fx 
)
Parameters
ep1p1
ep2p2
pss
fxx

Definition at line 924 of file partial_eval.c.

928 {
929  eformat_t ef;
930 
932  ep1, ep2, ps, fx);
933 
934  return ef;
935 }

References partial_eval_plus_or_minus_operator(), and PERFORM_ADDITION.

Referenced by partial_eval_plus_c_operator().

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

◆ partial_eval_plus_or_minus_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

Parameters
tokenoken
ep1p1
ep2p2
pss
fxx

Definition at line 792 of file partial_eval.c.

797 {
799  /* Automatic tools sometimes generate source code like "i - i" */
800  /* Could be improved with a commutative_expression_equal_p() if
801  cases arise */
802  if(expression_equal_p(*ep1, *ep2)) {
803  if(token==PERFORM_SUBTRACTION) {
804  ef.simpler = true;
805  ef.expr = expression_undefined; //int_to_expression(0);
806  ef.icoef = 0;
807  ef.ishift = 0;
808  }
809  else if(token==PERFORM_ADDITION) {
810  ef.simpler = true;
811  /* FI: no idea of the expression should be copied or not, let's
812  play safe. */
813  /* Here we should go down to see if *ep1 can be partially
814  evaluated */
815  eformat_t ef1 = partial_eval_expression_and_copy(*ep1, ps, fx);
816  ef.expr = ef1.expr;
817  ef.icoef = 2*ef1.icoef;
818  ef.ishift = 2*ef1.ishift;
819  /* FI: here I should get rid of ef1... */
820  }
821  else {
822  pips_internal_error("Ill. token %d\n", token);
823  }
824  }
825  else {
826  eformat_t ef1, ef2;
827 
828  ef1 = partial_eval_expression_and_copy(*ep1, ps, fx);
829  ef2 = partial_eval_expression_and_copy(*ep2, ps, fx);
830 
831  /* generate ef.icoef and ef.expr */
832  if( (ef1.icoef==ef2.icoef || ef1.icoef==-ef2.icoef)
833  && (ef1.icoef<-1 || ef1.icoef>1) ) {
834  /* factorize icoef */
835  ef.simpler=true;
836  if( (token==PERFORM_ADDITION && ef1.icoef==ef2.icoef)
837  || (token==PERFORM_SUBTRACTION && ef1.icoef==-ef2.icoef) ) {
838  /* addition */
840  ef1.expr,
841  ef2.expr);
842  ef.icoef= ef1.icoef;
843  }
844  else if( (ef1.icoef>1)
845  && (token==PERFORM_SUBTRACTION ? (ef2.icoef>0) : (ef2.icoef<0)) ) {
846  /* substraction e1-e2 */
848  ef1.expr,
849  ef2.expr);
850  ef.icoef= ef1.icoef;
851  }
852  else {
853  /* substraction e2-e1 */
855  ef2.expr,
856  ef1.expr);
857  ef.icoef= -ef1.icoef;
858  }
859  }
860  else if(ef1.icoef!=0 && ef2.icoef!=0) {
861  int c1 = ef1.icoef;
862  int c2 = (token==PERFORM_SUBTRACTION ? -ef2.icoef : ef2.icoef);
863  expression e1= generate_monome((c1>0 ? c1: -c1), ef1.expr);
864  expression e2= generate_monome((c2>0 ? c2: -c2), ef2.expr);
865 
866  /* generate without factorize, but for -1? */
867  ef.simpler= (ef1.simpler || ef2.simpler); /* not precise ?? */
868  if(c1*c2>0) {
870  e1, e2);
871  ef.icoef= (c1>0 ? 1 : -1);
872  }
873  else if(c1>0) {
875  e1, e2);
876  ef.icoef= 1;
877  }
878  else {
880  e2, e1);
881  ef.icoef= 1;
882  }
883  }
884  else {
885  ef.simpler= (ef1.simpler || ef2.simpler);
886  if(ef1.icoef==0) {
887  /* CA (9/9/97) condition <0 added in order to simplify
888  also expression like (J)+(-1) in (J-1) */
889  if(ef1.ishift<=0)
890  ef.simpler=true;
891  ef.expr=ef2.expr;
892  ef.icoef=(token==PERFORM_SUBTRACTION ? -ef2.icoef : ef2.icoef);
893  }
894  else if(ef2.icoef==0) {
895  /* FI: simplification i++ + 0? I do not understand Corinne's
896  code above. ef.ishift is generated below. I force simpler
897  because ef2.icoef==0 can result from a simplification */
898  ef.expr = ef1.expr;
899  ef.icoef = ef1.icoef;
900  ef.simpler=true;
901  }
902  else {
903  if(ef2.ishift<=0)
904  ef.simpler=true;
905  ef.expr=ef1.expr;
906  ef.icoef=ef1.icoef;
907  }
908  }
909 
910  /* generate ef.ishift */
911  if ((ef1.icoef==0 || ef1.ishift!=0)
912  && (ef2.icoef==0 || ef2.ishift!=0))
913  {
914  /* simplify shifts */
915  ef.simpler= true;
916  }
917 
918  ef.ishift= (token==PERFORM_SUBTRACTION ?
919  ef1.ishift-ef2.ishift : ef1.ishift+ef2.ishift);
920  }
921  return ef;
922 }
bool expression_equal_p(expression e1, expression e2)
Syntactic equality e1==e2.
Definition: expression.c:1347

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().

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

◆ partial_eval_power_operator()

eformat_t partial_eval_power_operator ( expression ep1,
expression ep2,
Psysteme  ps,
effects  fx 
)
Parameters
ep1p1
ep2p2
pss
fxx

Definition at line 1169 of file partial_eval.c.

1173 {
1174  eformat_t ef, ef1, ef2;
1175 
1176  ef1 = partial_eval_expression_and_copy(*ep1, ps, fx);
1177  ef2 = partial_eval_expression_and_copy(*ep2, ps, fx);
1178 
1179  if( ef1.icoef == 0 && ef2.icoef == 0 && ef2.ishift >= 0) {
1180  ef.icoef = 0;
1181  ef.ishift = ipow(ef1.ishift, ef2.ishift);
1183  ef.simpler = true;
1184  }
1185  else {
1186  regenerate_expression(&ef1, ep1);
1187  regenerate_expression(&ef2, ep2);
1188  ef = eformat_undefined;
1189  }
1190 
1191  return ef;
1192 }
int ipow(int vg, int vd)
FI: such a function should exist in Linear/arithmetique.
Definition: eval.c:769

References eformat_undefined, eformat::expr, expression_undefined, eformat::icoef, ipow(), eformat::ishift, partial_eval_expression_and_copy(), regenerate_expression(), and eformat::simpler.

+ Here is the call graph for this function:

◆ partial_eval_reference()

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)))));

Parameters
pss
fxx

Definition at line 436 of file partial_eval.c.

437 {
438  reference r;
439  entity var;
440  Pbase base_min = BASE_UNDEFINED;
441 
442  pips_assert("partial_eval_reference",
445  var = reference_variable(r);
446 
447  if(reference_indices(r) != NIL) {
448  MAPL(li, {
449  expression expr = EXPRESSION(CAR(li));
450 
452  EXPRESSION_(CAR(li)) = expr;
453  }, reference_indices(r));
454 
455  debug(9, "partial_eval_reference", "Array elements not evaluated\n");
456  return(eformat_undefined);
457  }
458 
459  /* FI: this test may be wrong for enum variables? Does it matter?
460  what can you do with enum anyway? Well, they can be replaced by
461  their values */
462  if(!type_variable_p(entity_type(var)) ||
464  pips_debug(9, "Reference to a non-scalar-integer variable %s cannot be evaluated\n",
465  entity_name(var));
466  return(eformat_undefined);
467  }
468 
469  if (SC_UNDEFINED_P(ps)) {
470  pips_debug(9, "No precondition information\n");
471  pips_internal_error("Probably corrupted precondition");
472  return(eformat_undefined);
473  }
474 
475  if(entity_written_p(var, fx)) {
476  /* entity cannot be replaced */
477  debug(9, "partial_eval_reference",
478  "Write Reference to variable %s cannot be evaluated\n",
479  entity_name(var));
480  return(eformat_undefined);
481  }
482 
483  if(live_loop_index_p(var)) {
484  pips_debug(9, "Index %s cannot be evaluated\n", entity_name(var));
485  return(eformat_undefined);
486  }
487 
488  /* faire la Variable */
489  /* verification de la presence de la variable dans ps */
490  base_min = sc_to_minimal_basis(ps);
491  if(base_contains_variable_p(base_min, (Variable) var)) {
492  bool feasible;
493  Value min, max;
494  Psysteme ps1 = sc_dup(ps);
495 
496  /* feasible = sc_minmax_of_variable(ps1, (Variable) var, &min, &max); */
497  feasible = sc_minmax_of_variable2(ps1, (Variable) var, &min, &max);
498  if (! feasible) {
499  pips_user_warning("Not feasible system:"
500  " module contains some dead code.\n");
501  }
502  if ( value_eq(min,max) ) {
503  eformat_t ef;
504 
505  /* var is constant and has to be replaced */
506  ifdebug(9) {
507  pips_debug(9, "Constant to replace: \n");
508  print_expression(e);
509  }
510 
511  ef.icoef = 0;
512  ef.ishift = VALUE_TO_INT(min);
514  ef.simpler = true;
515  return(ef);
516 
517  /* new_expr=int_to_expression((int)min); */
518  /* replace expression_normalized(e) with
519  expression_normalized(new_expr) */
520  /* free_normalized(expression_normalized(e));
521  expression_normalized(e) = expression_normalized(new_expr);
522  expression_normalized(new_expr) = normalized_undefined; */
523 
524  /* replace expression_syntax(e) with
525  expression_syntax(new_expr) */
526  /*
527  free_syntax(expression_syntax((e)));
528  expression_syntax(e) = expression_syntax(new_expr);
529  expression_syntax(new_expr) = syntax_undefined;
530 
531  free_expression(new_expr);
532 
533 
534 
535 
536  if ( get_debug_level() == 9) {
537  debug(9, "partial_eval_reference",
538  "Constant replaced by expression: \n");
539  print_to_expressionession(e);
540  expression_consistent_p(e);
541  pips_assert("partial_eval_reference",
542  syntax_call_p(expression_syntax(e)));
543  } */
544  }
545  /* return(entity_initial(call_function(syntax_call(expression_syntax(e)))));
546  */
547  return(eformat_undefined);
548  }
549  base_rm(base_min);
550  return(eformat_undefined);
551 }
#define VALUE_TO_INT(val)
int Value
#define value_eq(v1, v2)
bool operators on values
bool base_contains_variable_p(Pbase b, Variable v)
bool base_contains_variable_p(Pbase b, Variable v): returns true if variable v is one of b's elements...
Definition: base.c:136
#define min(a, b)
#define max(a, b)
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_user_warning
Definition: misc-local.h:146
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
bool entity_written_p(entity ent, effects fx)
Definition: partial_eval.c:198
void print_expression(expression e)
no file descriptor is passed to make is easier to use in a debugging stage.
Definition: expression.c:58
type ultimate_type(type)
Definition: type.c:3466
#define syntax_reference_p(x)
Definition: ri.h:2728
#define basic_int_p(x)
Definition: ri.h:614
#define syntax_reference(x)
Definition: ri.h:2730
#define entity_name(x)
Definition: ri.h:2790
#define type_variable_p(x)
Definition: ri.h:2947
#define variable_basic(x)
Definition: ri.h:3120
Pbase sc_to_minimal_basis(Psysteme ps)
creation d'une base contenant toutes les variables apparaissant avec des coefficients non-nuls dans l...
Definition: sc_alloc.c:76
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
bool sc_minmax_of_variable2(volatile Psysteme ps, Variable var, Value *pmin, Value *pmax)
void sc_minmax_of_variable2(Psysteme ps, Variable var, Value *pmin, *pmax): examine un systeme pour t...
Definition: sc_eval.c:330
#define base_rm(b)
void * Variable
arithmetique is a requirement for vecteur, but I do not want to inforce it in all pips files....
Definition: vecteur-local.h:60
#define BASE_UNDEFINED

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().

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

◆ partial_eval_statement()

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

Parameters
stmtstatement 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));

Parameters
stmttmt

Definition at line 1695 of file partial_eval.c.

1696 {
1699 
1700  pips_assert("internal current_statement was reseted",
1704 
1705  pips_debug(8, "begin with tag %d\n", instruction_tag(inst));
1706 
1710  }
1711 
1712  switch(instruction_tag(inst)) {
1713  case is_instruction_block :
1714  {
1715  /* This is no longer useful with the new representation of C
1716  declarations. */
1717  if(false) {
1719  value v = entity_initial(e);
1720  if(value_expression_p(v))
1722  stmt_prec(stmt),
1723  stmt_to_fx(stmt,fx_map));
1724  }
1725  }
1726  } break;
1727  case is_instruction_test :
1728  {
1729  test t = instruction_test(inst);
1731  stmt_prec(stmt),
1732  stmt_to_fx(stmt,fx_map));
1733  ifdebug(9) {
1735  pips_assert("stmt is consistent", statement_consistent_p(stmt));
1736  }
1737  } break;
1738  case is_instruction_loop :
1739  {
1740  loop l = instruction_loop(inst);
1741  range r = loop_range(l);
1742  effects fx = stmt_to_fx(stmt,fx_map);
1743  Psysteme sc = stmt_prec(stmt);
1744 
1745  /* Assuming no side-effects in loop bounds, sc is constant... */
1746 
1748  sc,
1749  fx);
1751  sc,
1752  fx);
1754  sc,
1755  fx);
1758 
1759  ifdebug(9) {
1761  pips_assert("stmt is consistent", statement_consistent_p(stmt));
1762  }
1763  } break;
1764  case is_instruction_forloop :
1765  {
1766  forloop fl = instruction_forloop(inst);
1767 
1769  stmt_prec(stmt),
1770  stmt_to_fx(stmt,fx_map));
1771  // FI: wrong precondition!
1773  stmt_prec(stmt),
1774  stmt_to_fx(stmt,fx_map));
1775  // FI: wrong precondition!
1777  stmt_prec(stmt),
1778  stmt_to_fx(stmt,fx_map));
1779  //add_live_loop_index(loop_index(l));
1780  //rm_live_loop_index(loop_index(l));
1781 
1782  if(get_debug_level()>=9) {
1785  }
1786  } break;
1788  {
1789  /* The whileloop precondition cannot be used to evaluate the
1790  while condition. It must be unioned with the body postcondition.
1791  partial_eval_expression_and_regenerate(&whileloop_condition(l),
1792  stmt_prec(stmt),
1793  stmt_to_fx(stmt,fx_map));
1794  */
1795  /* Also, two kinds of while must be handled */
1796  /* Short term fix... we might as well not try anything for
1797  the while condition */
1798  /* partial_eval_expression_and_regenerate(&whileloop_condition(l),
1799  SC_UNDEFINED, stmt_to_fx(stmt,fx_map));
1800  */
1801 
1802  ifdebug(9) {
1804  pips_assert("stmt is consistent", statement_consistent_p(stmt));
1805  }
1806  } break;
1807  case is_instruction_call :
1808  {
1810  stmt_prec(stmt),
1811  stmt_to_fx(stmt,fx_map));
1812  } break;
1813  case is_instruction_goto:
1814  break;
1816  break;
1819  stmt_prec(stmt),
1820  stmt_to_fx(stmt,fx_map));
1821  break;
1822  default :
1823  pips_internal_error("Bad instruction tag %d", instruction_tag(inst));
1824  }
1826  pop_statement_global_stack(); // for warnings
1827 }
bool statement_consistent_p(statement p)
Definition: ri.c:2195
statement_effects get_proper_rw_effects(void)
bool declaration_statement_p(statement)
Had to be optimized according to Beatrice Creusillet.
Definition: statement.c:224
effects stmt_to_fx(statement stmt, statement_effects fx_map)
returns proper effects associated to statement stmt
Definition: partial_eval.c:179
void partial_eval_call_and_regenerate(call ca, Psysteme ps, effects fx)
Definition: partial_eval.c:553
static void rm_live_loop_index(entity i)
Definition: partial_eval.c:164
void partial_eval_declarations(list el, Psysteme pre_sc, effects fx)
static void add_live_loop_index(entity i)
Definition: partial_eval.c:157
Psysteme stmt_prec(statement stmt)
Definition: partial_eval.c:230
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
#define is_instruction_block
soft block->sequence transition
statement pop_statement_global_stack(void)
Definition: static.c:352
void push_statement_on_statement_global_stack(statement)
Definition: static.c:333
#define forloop_initialization(x)
Definition: ri.h:1366
#define range_upper(x)
Definition: ri.h:2290
#define forloop_increment(x)
Definition: ri.h:1370
#define instruction_loop(x)
Definition: ri.h:1520
#define range_increment(x)
Definition: ri.h:2292
@ is_instruction_goto
Definition: ri.h:1473
@ is_instruction_unstructured
Definition: ri.h:1475
@ is_instruction_whileloop
Definition: ri.h:1472
@ is_instruction_expression
Definition: ri.h:1478
@ is_instruction_test
Definition: ri.h:1470
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_forloop
Definition: ri.h:1477
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define instruction_forloop(x)
Definition: ri.h:1538
#define instruction_expression(x)
Definition: ri.h:1541
#define test_condition(x)
Definition: ri.h:2833
#define range_lower(x)
Definition: ri.h:2288
#define statement_declarations(x)
Definition: ri.h:2460
#define statement_instruction(x)
Definition: ri.h:2458
#define instruction_call(x)
Definition: ri.h:1529
#define loop_range(x)
Definition: ri.h:1642
#define forloop_condition(x)
Definition: ri.h:1368
#define instruction_test(x)
Definition: ri.h:1517
#define statement_undefined_p(x)
Definition: ri.h:2420
#define value_expression_p(x)
Definition: ri.h:3080
#define value_expression(x)
Definition: ri.h:3082
#define loop_index(x)
Definition: ri.h:1640
#define statement_undefined
Definition: ri.h:2419
Definition: statement.c:54

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().

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

◆ partial_eval_syntax()

eformat_t partial_eval_syntax ( expression  e,
Psysteme  ps,
effects  fx 
)
Parameters
pss
fxx

Definition at line 355 of file partial_eval.c.

356 {
357  eformat_t ef;
358  syntax s = expression_syntax(e);
359 
360  switch (syntax_tag(s)) {
361  case is_syntax_reference:
362  ef = partial_eval_reference(e, ps, fx);
363  break;
364  case is_syntax_range:
365  ef = eformat_undefined;
366  break;
367  case is_syntax_call:
368  ef = partial_eval_call_expression(e, ps, fx);
369  break;
370  case is_syntax_cast: {
371  cast c = syntax_cast(s);
372 
374  ef = eformat_undefined;
375  break;
376  }
379 
382  }
383  else if(get_bool_property("EVAL_SIZEOF")) {
384  type t = sizeofexpression_type(soe);
385  int tms = type_memory_size(t);
388  )
389  );
390  }
391  ef = eformat_undefined;
392  break;
393  }
394  case is_syntax_subscript: {
395  subscript sub = syntax_subscript(s);
397  for(list iter=subscript_indices(sub);!ENDP(iter);POP(iter))
399 
400  /*
401  MAPL(ce, {
402  partial_eval_expression_and_regenerate(&(EXPRESSION(CAR(ce))), ps, fx);
403  }, el);
404  */
405 
406  ef = eformat_undefined;
407  break;
408  }
409  case is_syntax_application: {
411 
413 
414  /*
415  MAPL(ce, {
416  partial_eval_expression_and_regenerate(&(EXPRESSION(CAR(ce))), ps, fx);
417  }, al);
418  */
419  ef = eformat_undefined;
420  break;
421  }
422  case is_syntax_va_arg:
423  ef = eformat_undefined;
424  break;
425  default:
426  pips_internal_error("case default");
427  abort();
428  }
429 
430  if (get_debug_level()==9)
431  print_eformat(ef, "after partial_eval_syntax");
432 
433  return(ef);
434 }
call make_call(entity a1, list a2)
Definition: ri.c:269
syntax make_syntax_call(call _field_)
Definition: ri.c:2500
entity int_to_entity(_int c)
Definition: constant.c:453
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define abort()
Definition: misc-local.h:53
eformat_t partial_eval_call_expression(expression exp, Psysteme ps, effects fx)
Definition: partial_eval.c:664
eformat_t partial_eval_reference(expression e, Psysteme ps, effects fx)
Definition: partial_eval.c:436
void update_expression_syntax(expression e, syntax s)
frees expression syntax of e and replace it by the new syntax s
Definition: expression.c:3564
int type_memory_size(type)
Definition: size.c:248
#define syntax_tag(x)
Definition: ri.h:2727
#define sizeofexpression_type(x)
Definition: ri.h:2406
#define sizeofexpression_expression(x)
Definition: ri.h:2409
#define syntax_cast(x)
Definition: ri.h:2739
#define syntax_application(x)
Definition: ri.h:2748
@ is_syntax_range
Definition: ri.h:2692
@ is_syntax_application
Definition: ri.h:2697
@ is_syntax_cast
Definition: ri.h:2694
@ is_syntax_call
Definition: ri.h:2693
@ is_syntax_va_arg
Definition: ri.h:2698
@ is_syntax_reference
Definition: ri.h:2691
@ is_syntax_sizeofexpression
Definition: ri.h:2695
@ is_syntax_subscript
Definition: ri.h:2696
#define cast_expression(x)
Definition: ri.h:747
#define subscript_indices(x)
Definition: ri.h:2563
#define syntax_sizeofexpression(x)
Definition: ri.h:2742
#define sizeofexpression_expression_p(x)
Definition: ri.h:2407
#define subscript_array(x)
Definition: ri.h:2561
#define application_function(x)
Definition: ri.h:508
#define syntax_subscript(x)
Definition: ri.h:2745

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().

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

◆ partial_eval_unary_operator()

eformat_t partial_eval_unary_operator ( entity  func,
cons la,
Psysteme  ps,
effects  fx 
)

EXPRESSION(CAR(la));

operator can be a pre/post inc/dec C operator

Parameters
funcunc
laa
pss
fxx

Definition at line 680 of file partial_eval.c.

681 {
682  eformat_t ef;
683  expression *sub_ep;
684 
685  pips_assert("one argument", gen_length(la)==1);
686  sub_ep = /*&EXPRESSION(CAR(la));*/ (expression*) REFCAR(la);
687 
688  if (ENTITY_UNARY_MINUS_P(func)) {
689  ef = partial_eval_expression_and_copy(*sub_ep, ps, fx);
690 
691  if(ef.icoef==0
692  || ((ef.icoef<0 || ef.icoef>1)
693  && (ef.ishift<=0))
694  ) {
695  ef.simpler= true;
696  }
697 
698  ef.icoef= -(ef.icoef);
699  ef.ishift= -(ef.ishift);
700  }
701  else if(ENTITY_ADDRESS_OF_P(func)) {
702  ef = partial_eval_expression_and_copy(*sub_ep, ps, fx);
703  if(ef.icoef!=0) // it means we should not generate a constant now
705  ef = eformat_undefined;
706  }
707  else {
708  /* operator can be a pre/post inc/dec C operator */
710  ef = eformat_undefined;
711  }
712  return(ef);
713 }
#define ENTITY_UNARY_MINUS_P(e)
#define ENTITY_ADDRESS_OF_P(e)

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().

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

◆ partial_eval_update_operators()

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.

1202 {
1203  eformat_t ef, ef1, ef2;
1204 
1205  /* You do not want to change "n = 1; n = 1;" into n = 1; 1 = 1;" */
1206  if(!(expression_reference_p(*ep1)
1208  ef1 = partial_eval_expression_and_copy(*ep1, ps, fx);
1209  regenerate_expression(&ef1, ep1);
1210  }
1211 
1212  ef2 = partial_eval_expression_and_copy(*ep2, ps, fx);
1213  regenerate_expression(&ef2, ep2);
1214 
1215  ef = eformat_undefined;
1216 
1217  return ef;
1218 }
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
bool reference_scalar_p(reference r)
This function returns true if Reference r is scalar.
Definition: expression.c:3530

References eformat_undefined, expression_reference(), expression_reference_p(), partial_eval_expression_and_copy(), reference_scalar_p(), and regenerate_expression().

+ Here is the call graph for this function:

◆ print_eformat()

void print_eformat ( eformat_t  ef,
char *  name 
)
Parameters
eff
nameame

Definition at line 277 of file partial_eval.c.

278 {
279  (void) printf("eformat %s = %d x EXPR + %d, %ssimpler, with EXPR:\n",
280  name, ef.icoef, ef.ishift, (ef.simpler ? "" : "NOT "));
282 }
int printf()

References eformat::expr, eformat::icoef, eformat::ishift, print_expression(), printf(), and eformat::simpler.

Referenced by partial_eval_expression_and_regenerate(), and partial_eval_syntax().

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

◆ regenerate_call()

void regenerate_call ( eformat_t efp,
call  ca 
)

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

Parameters
efpfp
caa

Definition at line 1589 of file partial_eval.c.

1590 {
1592  regenerate_expression(efp, &e);
1593  if(expression_undefined_p(e)) {
1594  /* Nothing to do */
1595  ;
1596  }
1597  else if(expression_call_p(e)) {
1599  //list al = call_arguments(ca);
1600  call_function(ca) = call_function(nc);
1601  call_arguments(ca) = call_arguments(nc);
1602  // gen_full_free_list(al);
1603  }
1604  else if(expression_reference_p(e)) {
1605  /* We are in trouble... */
1607  /* Any memory write effect? */
1608  if(effects_all_read_p(el)) {
1610  call_arguments(ca) = NIL;
1611  }
1612  else {
1613  /* Do not change the initial call */
1614  free_expression(e);
1615  }
1616  }
1617  else {
1618  /* We are even more in trouble */
1619  pips_internal_error("Unexpected case.");
1620  }
1621 }
void free_expression(expression p)
Definition: ri.c:853
list expression_to_proper_effects(expression)
bool effects_all_read_p(list)
Check that all effects in el are read effects.
Definition: effects.c:1141
#define CONTINUE_FUNCTION_NAME
bool expression_call_p(expression e)
Definition: expression.c:415

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().

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

◆ regenerate_expression()

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

Parameters
efpfp
epp

Definition at line 1526 of file partial_eval.c.

1527 {
1529  /* nothing to do because expressions are the same */
1530  }
1531  else if(!get_bool_property("PARTIAL_EVAL_ALWAYS_SIMPLIFY") && !efp->simpler) {
1532  /* simply free efp->expr */
1533  /* ******commented out for debug******* */
1534  //free_expression(efp->expr);
1535  efp->expr= expression_undefined; /* useless */
1536  }
1537  else {
1538  expression tmp_expr;
1539 
1540  /* *ep must be freed */
1541  /* ?? ******commented out for debug******* */
1542  /* free_expression(*ep); */
1543 
1544  if(efp->icoef != 0) {
1545  /* check */
1546  pips_assert("regenerate_expression",
1547  efp->expr != expression_undefined);
1548 
1549  if(efp->icoef == 1) {
1550  tmp_expr= efp->expr;
1551  }
1552  else if(efp->icoef == -1) {
1553  /* generate unary_minus */
1555  efp->expr);
1556  }
1557  else {
1558  /* generate product */
1560  int_to_expression(efp->icoef),
1561  efp->expr);
1562  }
1563 
1564  if(efp->ishift != 0) {
1565  /* generate addition or substraction */
1566  string operator = (efp->ishift>0) ? PLUS_OPERATOR_NAME
1568  tmp_expr= MakeBinaryCall(entity_intrinsic(operator),
1569  tmp_expr,
1570  int_to_expression(ABS(efp->ishift)));
1571  }
1572  }
1573  else {
1574  /* check */
1575  pips_assert("the expression is undefined",
1576  efp->expr == expression_undefined);
1577  /* final expression is constant efp->ishift */
1578  tmp_expr= int_to_expression(efp->ishift);
1579  }
1580 
1581  /* replace *ep by tmp_expr */
1582  *ep = tmp_expr;
1583  }
1584 }
#define ABS(x)
was: #define value_mult(v,w) value_direct_multiply(v,w) #define value_product(v,w) value_direct_produ...

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().

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

◆ reset_live_loop_indices()

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.

136 {
137  /* The index set should be empty when leaving partial eval */
138  pips_assert("reset_live_loop_indices", ENDP(live_loop_indices));
139  if(!ENDP(live_loop_indices)) {
141  }
143 }
void free_arguments(cons *args)
Definition: arguments.c:218

References ENDP, free_arguments(), list_undefined, live_loop_indices, and pips_assert.

Referenced by partial_eval().

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

◆ rm_live_loop_index()

static void rm_live_loop_index ( entity  i)
static

Definition at line 164 of file partial_eval.c.

165 {
166  pips_assert("set_live_loop_indices", live_loop_indices!=list_undefined);
168 }
cons * arguments_rm_entity(cons *a, entity e)
Definition: arguments.c:94

References arguments_rm_entity(), list_undefined, live_loop_indices, and pips_assert.

Referenced by partial_eval_statement().

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

◆ set_live_loop_indices()

void set_live_loop_indices ( void  )

cproto-generated files

partial_eval.c

Definition at line 129 of file partial_eval.c.

130 {
131  pips_assert("set_live_loop_indices", live_loop_indices==list_undefined);
133 }

References list_undefined, live_loop_indices, NIL, and pips_assert.

Referenced by partial_eval().

+ Here is the caller graph for this function:

◆ stmt_prec()

Psysteme stmt_prec ( statement  stmt)

pips_assert("stmt_prec", t != transformer_undefined);

Parameters
stmttmt

Definition at line 230 of file partial_eval.c.

231 {
232  transformer t;
233 
234  pips_assert("stmt_prec", stmt != statement_undefined);
235 
236  pips_debug(9,
237  "Look for preconditions for statement at %p (ordering %td, number %td):\n",
239 
241 
243 
244  /* pips_assert("stmt_prec", t != transformer_undefined);*/
245 
246  return(t==transformer_undefined ?
247  SC_UNDEFINED :
249 
250 }
#define HASH_UNDEFINED_VALUE
value returned by hash_get() when the key is not found; could also be called HASH_KEY_NOT_FOUND,...
Definition: newgen_hash.h:56
#define transformer_undefined
Definition: ri.h:2847
#define statement_ordering(x)
Definition: ri.h:2454
#define transformer_relation(x)
Definition: ri.h:2873
#define statement_number(x)
Definition: ri.h:2452
#define predicate_system(x)
Definition: ri.h:2069

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().

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

◆ stmt_to_fx()

effects stmt_to_fx ( statement  stmt,
statement_effects  fx_map 
)

returns proper effects associated to statement stmt

Parameters
stmttmt
fx_mapx_map

Definition at line 179 of file partial_eval.c.

180 {
181  effects fx;
182 
183  pips_assert("stmt is defined", stmt != statement_undefined);
184 
185  pips_debug(9,
186  "Look for effects for statement at %p (ordering %td, number %td):\n",
188 
189  fx = apply_statement_effects(fx_map, stmt);
190  ifdebug(5)
191  {
193  }
194 
195  return(fx);
196 }
effects apply_statement_effects(statement_effects f, statement k)
Definition: effects.c:1007
#define print_effects(e)
Definition: print.c:334

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().

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

◆ transformer_map_print()

void transformer_map_print ( void  )

Definition at line 252 of file partial_eval.c.

253 {
254  FILE * f =stderr;
256 
258 
259  HASH_MAP(k, v, {
260  fprintf(f, "\nFor statement at %p (ordering %td, number %td):\n",
261  k,
265  },
266  htp);
267 }
void hash_table_print_header(hash_table htp, FILE *fout)
this function prints the header of the hash_table pointed to by htp on the opened stream fout.
Definition: hash.c:510
#define HASH_MAP(k, v, code, ht)
Definition: newgen_hash.h:60
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
#define print_transformer(t)
Definition: print.c:357
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...

References f(), fprintf(), get_precondition_map(), HASH_MAP, hash_table_print_header(), print_transformer, statement_number, and statement_ordering.

Referenced by init_use_preconditions().

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

Variable Documentation

◆ binary_operator_switch

struct perform_switch binary_operator_switch[]
static
Initial value:
= {
{0 , 0}
}
eformat_t partial_eval_mod_operator(expression *ep1, expression *ep2, Psysteme ps, effects fx)
eformat_t partial_eval_max_operator(expression *ep1, expression *ep2, Psysteme ps, effects fx)
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.
eformat_t partial_eval_c_mod_operator(expression *ep1, expression *ep2, Psysteme ps, effects fx)
eformat_t partial_eval_mult_operator(expression *ep1, expression *ep2, Psysteme ps, effects fx)
Definition: partial_eval.c:727
eformat_t partial_eval_div_operator(expression *ep1, expression *ep2, Psysteme ps, effects fx)
eformat_t partial_eval_minus_c_operator(expression *ep1, expression *ep2, Psysteme ps, effects fx)
Definition: partial_eval.c:972
eformat_t partial_eval_plus_c_operator(expression *ep1, expression *ep2, Psysteme ps, effects fx)
Definition: partial_eval.c:937
eformat_t partial_eval_power_operator(expression *ep1, expression *ep2, Psysteme ps, effects fx)
eformat_t partial_eval_min_operator(expression *ep1, expression *ep2, Psysteme ps, effects fx)
#define MAX_OPERATOR_NAME
#define POWER_OPERATOR_NAME
#define BITWISE_OR_UPDATE_OPERATOR_NAME
#define DIVIDE_UPDATE_OPERATOR_NAME
#define MAX0_OPERATOR_NAME
#define MIN0_OPERATOR_NAME
#define LEFT_SHIFT_UPDATE_OPERATOR_NAME
#define MULTIPLY_UPDATE_OPERATOR_NAME
#define MINUS_UPDATE_OPERATOR_NAME
#define RIGHT_SHIFT_UPDATE_OPERATOR_NAME
#define PLUS_UPDATE_OPERATOR_NAME
#define MINUS_C_OPERATOR_NAME
#define ASSIGN_OPERATOR_NAME
Definition: ri-util-local.h:95
#define PLUS_C_OPERATOR_NAME
#define MIN_OPERATOR_NAME

Referenced by partial_eval_binary_operator().

◆ eformat_undefined

eformat_t eformat_undefined = {expression_undefined, 1, 0, false}
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().

◆ live_loop_indices

list live_loop_indices = list_undefined
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().

◆ partial_eval_current_statement

statement partial_eval_current_statement =statement_undefined
static

Definition at line 127 of file partial_eval.c.

Referenced by partial_eval_min_or_max_operator(), and partial_eval_statement().