PIPS
forward_substitution.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "effects.h"
#include "dg.h"
#include "graph.h"
#include "ri-util.h"
#include "prettyprint.h"
#include "effects-util.h"
#include "text-util.h"
#include "database.h"
#include "misc.h"
#include "pipsdbm.h"
#include "resources.h"
#include "effects-generic.h"
#include "effects-simple.h"
#include "properties.h"
#include "expressions-local.h"
#include "expressions.h"
#include "ricedg.h"
+ Include dependency graph for forward_substitution.c:

Go to the source code of this file.

Data Structures

struct  t_substitution
 structure to hold a substitution to be performed forward. More...
 
struct  s_p_s
 

Typedefs

typedef dg_arc_label arc_label
 
typedef dg_vertex_label vertex_label
 
typedef struct t_substitutionp_substitution
 

Functions

static p_substitution make_substitution (statement source, reference ref, expression val)
 newgen-looking make/free More...
 
static void free_substitution (p_substitution subs)
 
static bool no_write_effects_on_var (entity var, list le)
 
static bool functionnal_on_effects (reference ref, list le)
 
static bool functionnal_on (reference ref, statement s)
 returns whether there is other write proper effect than on var or if some variable conflicting with var is read... More...
 
static p_substitution substitution_candidate (statement s, bool only_scalar)
 Whether it is a candidate of a substitution operation. More...
 
static bool cool_enough_for_a_last_substitution (statement s)
 x = a(i) ; a(j) = x ; More...
 
static bool other_cool_enough_for_a_last_substitution (statement s, reference ref)
 s = r ; s = s + w ; // read THEN write... More...
 
static void perform_substitution_in_expression (expression e, p_substitution subs)
 do perform the substitution var -> val everywhere in s More...
 
static bool call_flt (call c, p_substitution subs)
 
static void perform_substitution (p_substitution subs, void *s)
 
static void perform_substitution_in_assign (p_substitution subs, statement s)
 
static bool some_conflicts_between (hash_table successors, statement s1, statement s2, p_substitution sub)
 whether there are some conflicts between s1 and s2 according to successor table successors More...
 
static bool do_substitute (statement anext, struct s_p_s *param)
 
static bool fs_filter (statement stat, graph dg)
 top-down forward substitution of reference in SEQUENCE only. More...
 
bool forward_substitute (const char *module_name)
 interface to pipsmake. More...
 

Typedef Documentation

◆ arc_label

Definition at line 60 of file forward_substitution.c.

◆ p_substitution

typedef struct t_substitution * p_substitution

◆ vertex_label

Definition at line 61 of file forward_substitution.c.

Function Documentation

◆ call_flt()

static bool call_flt ( call  c,
p_substitution  subs 
)
static

Definition at line 302 of file forward_substitution.c.

303 {
304  entity op = call_function(c);
307  {
308  expression lhs = binary_call_lhs(c);
310  gen_recurse_stop(lhs);
311  }
312  return true;
313 }
void gen_recurse_stop(void *obj)
Tells the recursion not to go in this object.
Definition: genClib.c:3251
#define binary_call_lhs(c)
#define ASSIGN_OPERATOR_NAME
Definition: ri-util-local.h:95
entity update_operator_to_regular_operator(entity op)
Returns the binary operator associated to a C update operator such as +=.
Definition: entity.c:2154
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
bool reference_equal_p(reference r1, reference r2)
Definition: expression.c:1500
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
#define call_function(x)
Definition: ri.h:709
#define entity_undefined_p(x)
Definition: ri.h:2762
reference ref
the statement where the definition was found.

References ASSIGN_OPERATOR_NAME, binary_call_lhs, call_function, entity_intrinsic(), entity_undefined_p, expression_reference(), expression_reference_p(), gen_recurse_stop(), t_substitution::ref, reference_equal_p(), same_entity_p(), and update_operator_to_regular_operator().

Referenced by perform_substitution().

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

◆ cool_enough_for_a_last_substitution()

static bool cool_enough_for_a_last_substitution ( statement  s)
static

x = a(i) ; a(j) = x ;

we can substitute x but it cannot be continued. just a hack for this very case at the time. maybe englobing parallel loops or dependence information could be use for a better decision? I'll think about it on request only.

Definition at line 220 of file forward_substitution.c.

221 {
223  bool ok = (x!=NULL);
225  return ok;
226 }
static void free_substitution(p_substitution subs)
static p_substitution substitution_candidate(statement s, bool only_scalar)
Whether it is a candidate of a substitution operation.
static bool ok
static char * x
Definition: split_file.c:159
structure to hold a substitution to be performed forward.

References free_substitution(), ok, substitution_candidate(), and x.

Referenced by do_substitute().

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

◆ do_substitute()

static bool do_substitute ( statement  anext,
struct s_p_s param 
)
static

for some special case the substitution is performed. in some cases effects should be updated?

now STOP propagation!

Definition at line 389 of file forward_substitution.c.

390 {
391  if(!statement_block_p(anext))
392  {
393  ifdebug(1) {
394  pips_debug(1, "with statement:\n");
395  print_statement(anext);
396  }
397  if (some_conflicts_between(param->successors,param->subs->source, anext, param->subs))
398  {
399  /* for some special case the substitution is performed.
400  * in some cases effects should be updated?
401  */
402  if (cool_enough_for_a_last_substitution(anext))// &&
403  // !some_conflicts_between(param->successors,param->subs->source, anext, param->subs))
404  perform_substitution(param->subs, anext);
405  else
406  if (other_cool_enough_for_a_last_substitution(anext, param->subs->ref))
408  param->stop=true;
409 
410  /* now STOP propagation!
411  */
412  gen_recurse_stop(NULL);
413  }
414  else
415  perform_substitution(param->subs, anext);
416  }
417  return true;
418 }
static void perform_substitution(p_substitution subs, void *s)
static void perform_substitution_in_assign(p_substitution subs, statement s)
static bool some_conflicts_between(hash_table successors, statement s1, statement s2, p_substitution sub)
whether there are some conflicts between s1 and s2 according to successor table successors
static bool other_cool_enough_for_a_last_substitution(statement s, reference ref)
s = r ; s = s + w ; // read THEN write...
static bool cool_enough_for_a_last_substitution(statement s)
x = a(i) ; a(j) = x ;
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
#define statement_block_p(stat)
#define ifdebug(n)
Definition: sg.c:47
Definition: replace.c:135

References cool_enough_for_a_last_substitution(), gen_recurse_stop(), ifdebug, other_cool_enough_for_a_last_substitution(), perform_substitution(), perform_substitution_in_assign(), pips_debug, print_statement(), some_conflicts_between(), and statement_block_p.

Referenced by fs_filter().

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

◆ forward_substitute()

bool forward_substitute ( const char *  module_name)

interface to pipsmake.

forward_substitution.c

should have proper and cumulated effects...

set require resources.

do the job here:

return result and clean.

Parameters
module_nameodule_name

Definition at line 470 of file forward_substitution.c.

471 {
472  debug_on("FORWARD_SUBSTITUTE_DEBUG_LEVEL");
473 
474  /* set require resources.
475  */
481  graph dg = (graph) db_get_memory_resource(DBR_DG, module_name, true);
482 
483  /* do the job here:
484  */
486 
487  /* return result and clean.
488  */
490 
496 
497  debug_off();
498 
499  return true;
500 }
static graph dg
dg is the dependency graph ; FIXME : should not be static global ?
Definition: chains.c:124
void reset_proper_rw_effects(void)
void set_proper_rw_effects(statement_effects)
void set_cumulated_rw_effects(statement_effects)
void reset_cumulated_rw_effects(void)
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
static bool fs_filter(statement stat, graph dg)
top-down forward substitution of reference in SEQUENCE only.
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
Definition: genC.h:285
struct _newgen_struct_graph_ * graph
Definition: graph.h:31
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
void gen_null2(__attribute__((unused)) void *u1, __attribute__((unused)) void *u2)
idem with 2 args, to please overpeaky compiler checks
Definition: genClib.c:2758
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
#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
hash_table set_ordering_to_statement(statement s)
To be used instead of initialize_ordering_to_statement() to make sure that the hash table ots is in s...
Definition: ordering.c:172
void reset_ordering_to_statement(void)
Reset the mapping from ordering to statement.
Definition: ordering.c:185
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
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362

References db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, dg, fs_filter(), gen_context_recurse, gen_null2(), get_current_module_statement(), local_name_to_top_level_entity(), module_name(), reset_cumulated_rw_effects(), reset_current_module_entity(), reset_current_module_statement(), reset_ordering_to_statement(), reset_proper_rw_effects(), set_cumulated_rw_effects(), set_current_module_entity(), set_current_module_statement(), set_ordering_to_statement(), set_proper_rw_effects(), and statement_domain.

+ Here is the call graph for this function:

◆ free_substitution()

static void free_substitution ( p_substitution  subs)
static

Definition at line 126 of file forward_substitution.c.

127 {
128  if (subs) {
129  free_expression(subs->val);
130  free(subs);
131  }
132 }
void free_expression(expression p)
Definition: ri.c:853
void free(void *)
expression val
maybe could be a reference to allow arrays? SG:done

References free(), free_expression(), and t_substitution::val.

Referenced by cool_enough_for_a_last_substitution(), and fs_filter().

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

◆ fs_filter()

static bool fs_filter ( statement  stat,
graph  dg 
)
static

top-down forward substitution of reference in SEQUENCE only.

scan following statements and substitute while no conflicts.

Definition at line 423 of file forward_substitution.c.

424 {
425  if(statement_block_p(stat))
426  {
427  ifdebug(1) {
428  pips_debug(1, "considering block statement:\n");
429  print_statement(stat);
430  }
432  for(list ls = statement_block(stat);!ENDP(ls);POP(ls))
433  {
434  statement first = STATEMENT(CAR(ls));
435  if(assignment_statement_p(first))
436  {
437  ifdebug(1) {
438  pips_debug(1, "considering assignment statement:\n");
439  print_statement(first);
440  }
441  p_substitution subs = substitution_candidate(first, true);
442  if (subs)
443  {
444  /* scan following statements and substitute while no conflicts.
445  */
446  struct s_p_s param = { subs, successors,false};
447  bool once = false;
448  FOREACH(STATEMENT,next,CDR(ls))
449  {
450  param.stop=false;
452  if(param.stop) break;
453  else once=true;
454  }
455 
457  if(once && get_bool_property("FORWARD_SUBSTITUTE_OPTIMISTIC_CLEAN"))
459  }
460  }
461  }
463  }
464  return true;
465 }
static list successors(list l)
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
static bool do_substitute(statement anext, struct s_p_s *param)
instruction make_instruction_block(list statements)
Build an instruction block from a list of statements.
Definition: instruction.c:106
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
list statement_block(statement)
Get the list of block statements of a statement sequence.
Definition: statement.c:1338
statement update_statement_instruction(statement, instruction)
Replace the instruction in statement s by instruction i.
Definition: statement.c:3039
bool assignment_statement_p(statement)
Test if a statement is an assignment.
Definition: statement.c:135
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
hash_table statements_to_successors(list, graph)
creates a hash_table containing statements from statements as keys and their respective succesors acc...
Definition: util.c:1018
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
p_substitution subs

References assignment_statement_p(), CAR, CDR, dg, do_substitute(), ENDP, FOREACH, free_substitution(), gen_context_recurse, gen_null2(), get_bool_property(), hash_table_free(), ifdebug, make_instruction_block(), NIL, pips_debug, POP, print_statement(), STATEMENT, statement_block(), statement_block_p, statement_domain, statements_to_successors(), s_p_s::subs, substitution_candidate(), successors(), and update_statement_instruction().

Referenced by forward_substitute().

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

◆ functionnal_on()

static bool functionnal_on ( reference  ref,
statement  s 
)
static

returns whether there is other write proper effect than on var or if some variable conflicting with var is read...

(?) proper_effects must be available.

Definition at line 158 of file forward_substitution.c.

159 {
161 
162  ifdebug(1) {
163  pips_assert("efs is consistent", effects_consistent_p(efs));
164  }
165 
167 }
bool effects_consistent_p(effects p)
Definition: effects.c:541
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
effects load_proper_rw_effects(statement)
#define effects_effects(x)
Definition: effects.h:710
static bool functionnal_on_effects(reference ref, list le)
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172

References effects_consistent_p(), effects_effects, functionnal_on_effects(), ifdebug, load_proper_rw_effects(), pips_assert, and ref.

Referenced by substitution_candidate().

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

◆ functionnal_on_effects()

static bool functionnal_on_effects ( reference  ref,
list  le 
)
static
Parameters
leof effect

Definition at line 143 of file forward_substitution.c.

144 {
145  FOREACH(EFFECT, e, le) {
149  return false;
150  }
151  return true;
152 }
#define effect_write_p(eff)
#define effect_read_p(eff)
#define effect_scalar_p(eff) entity_scalar_p(effect_entity(eff))
#define effect_variable(e)
For COMPATIBILITY purpose only - DO NOT USE anymore.
action_kind effect_action_kind(effect)
Definition: effects.c:1055
#define action_kind_store_p(x)
Definition: effects.h:259
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
bool entities_may_conflict_p(entity e1, entity e2)
Check if two entities may conflict.
Definition: conflicts.c:984
#define reference_variable(x)
Definition: ri.h:2326

References action_kind_store_p, EFFECT, effect_action_kind(), effect_read_p, effect_variable, effect_write_p, entities_may_conflict_p(), FOREACH, ref, and reference_variable.

Referenced by functionnal_on().

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

◆ make_substitution()

static p_substitution make_substitution ( statement  source,
reference  ref,
expression  val 
)
static

newgen-looking make/free

Definition at line 96 of file forward_substitution.c.

97 {
98  p_substitution subs;
99  basic bval = basic_of_expression(val),
100  bref = basic_of_reference(ref);
101 
102  pips_assert("defined basics", !(basic_undefined_p(bval) || basic_undefined_p(bref)));
103 
104  subs = (p_substitution) malloc(sizeof(t_substitution));
105  pips_assert("malloc ok", subs);
106  subs->source = source;
107  subs->ref = ref;
108  if (basic_equal_p(bval, bref))
109  subs->val = copy_expression(val);
110  else
111  {
112  entity conv = basic_to_generic_conversion(bref);
113  if (entity_undefined_p(conv))
114  {
115  pips_user_warning("no conversion function...");
116  free(subs);
117  return NULL;
118  }
119  subs->val = MakeUnaryCall(conv,copy_expression(val));
120  }
121  free_basic(bval);
122  return subs;
123 }
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
void free_basic(basic p)
Definition: ri.c:107
struct t_substitution * p_substitution
void * malloc(YYSIZE_T)
#define pips_user_warning
Definition: misc-local.h:146
expression MakeUnaryCall(entity f, expression a)
Creates a call expression to a function with one argument.
Definition: expression.c:342
entity basic_to_generic_conversion(basic)
returns the corresponding generic conversion entity, if any.
Definition: type.c:2758
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
bool basic_equal_p(basic, basic)
Definition: type.c:927
basic basic_of_reference(reference)
Retrieves the basic of a reference in a newly allocated basic object.
Definition: type.c:1459
#define basic_undefined_p(x)
Definition: ri.h:557

References basic_equal_p(), basic_of_expression(), basic_of_reference(), basic_to_generic_conversion(), basic_undefined_p, copy_expression(), entity_undefined_p, free(), free_basic(), MakeUnaryCall(), malloc(), pips_assert, pips_user_warning, t_substitution::ref, ref, t_substitution::source, and t_substitution::val.

Referenced by substitution_candidate().

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

◆ no_write_effects_on_var()

static bool no_write_effects_on_var ( entity  var,
list  le 
)
static

Definition at line 134 of file forward_substitution.c.

135 {
136  FOREACH(EFFECT, e, le)
139  return false;
140  return true;
141 }

References action_kind_store_p, EFFECT, effect_action_kind(), effect_variable, effect_write_p, entities_may_conflict_p(), and FOREACH.

Referenced by other_cool_enough_for_a_last_substitution().

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

◆ other_cool_enough_for_a_last_substitution()

static bool other_cool_enough_for_a_last_substitution ( statement  s,
reference  ref 
)
static

s = r ; s = s + w ; // read THEN write...

it is an assignment

Definition at line 231 of file forward_substitution.c.

232 {
234  call c;
235  list args;
236  syntax svar;
237  entity var;
238  list le;
239 
240  if (!instruction_call_p(i))
241  return false;
242 
243  c = instruction_call(i);
245  return false;
246 
247  /* it is an assignment */
248  args = call_arguments(c);
249  pips_assert("2 args to =", gen_length(args)==2);
250  svar = expression_syntax(EXPRESSION(CAR(args)));
251  pips_assert("assign to a reference", syntax_reference_p(svar));
253 
254  if (!entity_scalar_p(var)) return false;
255 
258  gen_full_free_list(le);
259 
260  return cool;
261 }
list proper_effects_of_expression(expression)
static bool no_write_effects_on_var(entity var, list le)
void gen_full_free_list(list l)
Definition: genClib.c:1023
size_t gen_length(const list l)
Definition: list.c:150
#define ENTITY_ASSIGN_P(e)
bool entity_scalar_p(entity)
The concrete type of e is a scalar type.
Definition: variable.c:1113
#define syntax_reference_p(x)
Definition: ri.h:2728
#define syntax_reference(x)
Definition: ri.h:2730
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define instruction_call_p(x)
Definition: ri.h:1527
#define statement_instruction(x)
Definition: ri.h:2458
#define instruction_call(x)
Definition: ri.h:1529
#define call_arguments(x)
Definition: ri.h:711
#define expression_syntax(x)
Definition: ri.h:1247

References call_arguments, call_function, CAR, CDR, ENTITY_ASSIGN_P, entity_scalar_p(), EXPRESSION, expression_syntax, gen_full_free_list(), gen_length(), instruction_call, instruction_call_p, no_write_effects_on_var(), pips_assert, proper_effects_of_expression(), ref, reference_variable, statement_instruction, syntax_reference, and syntax_reference_p.

Referenced by do_substitute().

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

◆ perform_substitution()

static void perform_substitution ( p_substitution  subs,
void *  s 
)
static
Parameters
ssubstitution to perform where to do this

Definition at line 316 of file forward_substitution.c.

319 {
323  NULL);
325 }
static void perform_substitution_in_expression(expression e, p_substitution subs)
do perform the substitution var -> val everywhere in s
static bool call_flt(call c, p_substitution subs)
void gen_context_multi_recurse(void *o, void *context,...)
Multi-recursion with context function visitor.
Definition: genClib.c:3373
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
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 expression_domain
newgen_execution_domain_defined
Definition: ri.h:154
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58

References call_domain, call_flt(), expression_domain, gen_context_multi_recurse(), gen_null(), gen_true(), perform_substitution_in_expression(), and unnormalize_expression().

Referenced by do_substitute(), and perform_substitution_in_assign().

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

◆ perform_substitution_in_assign()

static void perform_substitution_in_assign ( p_substitution  subs,
statement  s 
)
static

special case

Definition at line 328 of file forward_substitution.c.

329 {
330  /* special case */
331  pips_assert("assign call", statement_call_p(s));
332 
333  call c = statement_call(s);
336  perform_substitution(subs, e);
337 }
call statement_call(statement)
Get the call of a statement.
Definition: statement.c:1406
bool statement_call_p(statement)
Definition: statement.c:364
#define binary_call_rhs(c)
#define reference_indices(x)
Definition: ri.h:2328

References binary_call_lhs, binary_call_rhs, EXPRESSION, expression_reference(), FOREACH, perform_substitution(), pips_assert, reference_indices, statement_call(), and statement_call_p().

Referenced by do_substitute().

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

◆ perform_substitution_in_expression()

static void perform_substitution_in_expression ( expression  e,
p_substitution  subs 
)
static

do perform the substitution var -> val everywhere in s

FI->FC: the syntax may be freed but not always the reference it contains because it can also be used in effects. The bug showed on transformations/Validation/fs01.f, fs02.f, fs04.f. I do not know why the effects are still used after the statement has been updated (?). The bug can be avoided by closing and opening the workspace which generates independent references in statements and in effects. Is there a link with the notion of cell = reference+preference?

Definition at line 265 of file forward_substitution.c.

266 {
267  syntax s = expression_syntax(e);
268  if (syntax_reference_p(s)) {
269 
271  if (reference_equal_p(r,subs->ref))
272  {
273  ifdebug(2) {
274  pips_debug(2,"substituing %s to %s\n",
275  expression_to_string(subs->val),
277  }
278  /* FI->FC: the syntax may be freed but not always the reference it
279  contains because it can also be used in effects. The bug showed on
280  transformations/Validation/fs01.f, fs02.f, fs04.f. I do not know why the
281  effects are still used after the statement has been updated (?). The bug
282  can be avoided by closing and opening the workspace which generates
283  independent references in statements and in effects. Is there a link with
284  the notion of cell = reference+preference? */
287  }
288  else
289  {
290  ifdebug(2) {
291  pips_debug(2,"not substituting ");
292  print_reference(subs->ref);
293  fputs(" to ",stderr);
294  print_reference(r);
295  fputs("\n",stderr);
296  }
297  }
298  }
299 }
syntax copy_syntax(syntax p)
SYNTAX.
Definition: ri.c:2442
string reference_to_string(reference r)
Definition: expression.c:87
string expression_to_string(expression e)
Definition: expression.c:77
void print_reference(reference r)
Definition: expression.c:142
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
#define syntax_undefined
Definition: ri.h:2676

References copy_syntax(), expression_syntax, expression_to_string(), ifdebug, pips_debug, print_reference(), t_substitution::ref, reference_equal_p(), reference_to_string(), syntax_reference, syntax_reference_p, syntax_undefined, update_expression_syntax(), and t_substitution::val.

Referenced by perform_substitution().

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

◆ some_conflicts_between()

static bool some_conflicts_between ( hash_table  successors,
statement  s1,
statement  s2,
p_substitution  sub 
)
static

whether there are some conflicts between s1 and s2 according to successor table successors

if there is a write-* conflict, we cannot do much

this case is safe

Definition at line 343 of file forward_substitution.c.

344 {
345  pips_assert("true", sub==sub);
346  pips_debug(2, "looking for conflict with statement\n");
347  ifdebug(2) { print_statement(s2); }
348  list s1_successors = hash_get(successors,s1);
349  FOREACH(SUCCESSOR,s,s1_successors)
350  {
352  pips_debug(2, "checking:\n");
353  ifdebug(2) { print_statement(ss); }
354  if(statement_in_statement_p(ss,s2))
355  {
357  {
358  /* if there is a write-* conflict, we cannot do much */
359  if ( effect_write_p(conflict_sink(c)) &&
361  {
362  /* this case is safe */
365  continue;
366  ifdebug(2) {
367  pips_debug(2, "conflict found on reference, with") ;
370  fputs("\n",stderr) ;
371  }
372  return true;
373  }
374  }
375  }
376  }
377 
378  pips_debug(2, "no conflict\n");
379  return false;
380 }
#define conflict_sink(x)
Definition: dg.h:167
#define CONFLICT(x)
CONFLICT.
Definition: dg.h:134
#define dg_arc_label_conflicts(x)
Definition: dg.h:201
#define conflict_source(x)
Definition: dg.h:165
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define successor_vertex(x)
Definition: graph.h:118
#define successor_arc_label(x)
Definition: graph.h:116
#define SUCCESSOR(x)
SUCCESSOR.
Definition: graph.h:86
bool statement_in_statement_p(statement, statement)
Definition: statement.c:4076
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:449
statement vertex_to_statement(vertex v)
Vertex_to_statement looks for the statement that is pointed to by vertex v.
Definition: util.c:45
s1
Definition: set.c:247

References action_kind_store_p, CONFLICT, conflict_sink, conflict_source, dg_arc_label_conflicts, effect_action_kind(), effect_any_reference, effect_write_p, ENDP, FOREACH, hash_get(), ifdebug, pips_assert, pips_debug, print_reference(), print_statement(), reference_indices, s1, statement_in_statement_p(), SUCCESSOR, successor_arc_label, successor_vertex, successors(), and vertex_to_statement().

Referenced by do_substitute().

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

◆ substitution_candidate()

static p_substitution substitution_candidate ( statement  s,
bool  only_scalar 
)
static

Whether it is a candidate of a substitution operation.

that is: (1) it is a call (2) it is an assignment call (3) the assigned variable is a scalar (sg: no longer true !) (4) there are no side effects in the expression

Note: a substitution candidate might be one after substitutions... but not before? So effects should be recomputed? or updated? eg: x = 1; x = x + 1;

of expression

CALL

ASSIGN

NO SIDE EFFECTS

Definition at line 179 of file forward_substitution.c.

180 {
181  pips_assert("true", only_scalar==only_scalar);
182  list /* of expression */ args;
183  call c;
184  entity fun;
185  syntax svar;
187 
188  if (!instruction_call_p(i)) return NULL; /* CALL */
189 
190  c = instruction_call(i);
191  fun = call_function(c);
192 
193  if (!ENTITY_ASSIGN_P(fun)) return NULL; /* ASSIGN */
194 
195 
196  args = call_arguments(c);
197  pips_assert("2 args to =", gen_length(args)==2);
198  svar = expression_syntax(EXPRESSION(CAR(args)));
199 
200  if(!syntax_reference_p(svar)) // What about subscripts ?
201  return NULL;
202 
204 
205  //if (only_scalar && ENDP(reference_indices(ref))) return NULL; /* SCALAR */
206 
207  if (!functionnal_on(ref, s)) return NULL; /* NO SIDE EFFECTS */
208 
209  return make_substitution(s, ref, EXPRESSION(CAR(CDR(args))));
210 }
static bool functionnal_on(reference ref, statement s)
returns whether there is other write proper effect than on var or if some variable conflicting with v...
static p_substitution make_substitution(statement source, reference ref, expression val)
newgen-looking make/free

References call_arguments, call_function, CAR, CDR, ENTITY_ASSIGN_P, EXPRESSION, expression_syntax, functionnal_on(), gen_length(), instruction_call, instruction_call_p, make_substitution(), pips_assert, ref, statement_instruction, syntax_reference, and syntax_reference_p.

Referenced by cool_enough_for_a_last_substitution(), and fs_filter().

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