PIPS
freia_transformations.c File Reference
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "effects.h"
#include "misc.h"
#include "ri-util.h"
#include "effects-util.h"
#include "callgraph.h"
#include "properties.h"
#include "resources.h"
#include "pipsdbm.h"
#include "control.h"
#include "effects-generic.h"
#include "freia.h"
#include "hwac.h"
+ Include dependency graph for freia_transformations.c:

Go to the source code of this file.

Data Structures

struct  vis_ctx
 look for a variable More...
 
struct  fcs_ctx
 
struct  subs_ctx
 util defined somewhere ?????? More...
 
struct  rssp_ctx
 
struct  shuffle_context
 

Macros

#define starts_with(s1, s2)   (strncmp(s1, s2, strlen(s2))==0) /**a la java */
 
#define entity_update_p(e)
 

Functions

static list remove_register (list lq)
 remove "register" qualifier from qualifier list More...
 
static bool sr_flt (statement s, int *number)
 
static void stmt_renumber (statement s)
 
static void vis_rwt (const reference r, vis_ctx *ctx)
 
static bool variable_is_used (statement s, entity var)
 
static bool fcs_count (statement s, fcs_ctx *ctx)
 
static bool freia_convergence_sequence_p (sequence sq)
 
static void ref_rwt (reference r, subs_ctx *ctx)
 
static void substitute_reference_variable (statement s, entity ovar, entity nvar)
 
static void maybe_unroll_while_rwt (whileloop wl, bool *changed)
 
static bool freia_unroll_while_for_spoc (statement s)
 
bool freia_unroll_while (const string module)
 freia_transformations.c More...
 
static entity freia_reduction_variable (const statement s)
 return the freia reduction entity, or NULL if it does not apply More...
 
static void sww_seq_rwt (const sequence sq, bool *changed)
 
bool freia_remove_scalar_ww_deps (const string module)
 
static entity address_of_scalar (expression e)
 "&v"? return v, else return NULL More...
 
static bool pointer_candidate_p (entity var)
 
static void rssp_ref (reference r, rssp_ctx *ctx)
 
bool remove_simple_scalar_pointers (const string module)
 
static bool sio_call_flt (call c, _UNUSED_ shuffle_context *ctx)
 
static void sio_ref_rwt (reference r, shuffle_context *ctx)
 
static void substitute_image_occurrences (void *s, shuffle_context *ctx)
 
static void seq_rwt (sequence sq, shuffle_context *ctx)
 
static void ref_count_rwt (reference r, hash_table counts)
 
static bool call_count_flt (call c, _UNUSED_ hash_table counts)
 
void freia_shuffle_move_forward (statement s)
 

Macro Definition Documentation

◆ entity_update_p

#define entity_update_p (   e)
Value:
ENTITY_MODULO_UPDATE_P(e) || ENTITY_PLUS_UPDATE_P(e) || \
ENTITY_MINUS_UPDATE_P(e) || ENTITY_LEFT_SHIFT_UPDATE_P(e) || \
ENTITY_RIGHT_SHIFT_UPDATE_P(e) || ENTITY_BITWISE_AND_UPDATE_P(e) || \
ENTITY_BITWISE_XOR_UPDATE_P(e) || ENTITY_BITWISE_OR_UPDATE_P(e))
#define ENTITY_PLUS_UPDATE_P(e)
#define ENTITY_BITWISE_AND_UPDATE_P(e)
#define ENTITY_BITWISE_OR_UPDATE_P(e)
#define ENTITY_MULTIPLY_UPDATE_P(e)
#define ENTITY_DIVIDE_UPDATE_P(e)
#define ENTITY_LEFT_SHIFT_UPDATE_P(e)

Definition at line 704 of file freia_transformations.c.

◆ starts_with

#define starts_with (   s1,
  s2 
)    (strncmp(s1, s2, strlen(s2))==0) /**a la java */

Definition at line 702 of file freia_transformations.c.

Function Documentation

◆ address_of_scalar()

static entity address_of_scalar ( expression  e)
static

"&v"? return v, else return NULL

Definition at line 484 of file freia_transformations.c.

485 {
486  if (!expression_call_p(e)) return NULL;
487  call c = expression_call(e);
488  if (!ENTITY_ADDRESS_OF_P(call_function(c))) return NULL;
489  list la = call_arguments(c);
490  pips_assert("one argument to &", gen_length(la)==1);
491  expression a = EXPRESSION(CAR(la));
492  if (!expression_reference_p(a)) return NULL;
494  if (reference_indices(r)) return NULL;
495  entity v = reference_variable(r);
496  if (entity_scalar_p(v))
497  return v;
498  return NULL;
499 }
size_t gen_length(const list l)
Definition: list.c:150
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define ENTITY_ADDRESS_OF_P(e)
bool expression_call_p(expression e)
Definition: expression.c:415
call expression_call(expression e)
Definition: expression.c:445
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
bool entity_scalar_p(entity)
The concrete type of e is a scalar type.
Definition: variable.c:1113
#define call_function(x)
Definition: ri.h:709
#define reference_variable(x)
Definition: ri.h:2326
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define reference_indices(x)
Definition: ri.h:2328
#define call_arguments(x)
Definition: ri.h:711
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References call_arguments, call_function, CAR, ENTITY_ADDRESS_OF_P, entity_scalar_p(), EXPRESSION, expression_call(), expression_call_p(), expression_reference(), expression_reference_p(), gen_length(), pips_assert, reference_indices, and reference_variable.

Referenced by remove_simple_scalar_pointers(), and rssp_ref().

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

◆ call_count_flt()

static bool call_count_flt ( call  c,
_UNUSED_ hash_table  counts 
)
static

Definition at line 850 of file freia_transformations.c.

851 {
853  {
854  list args = call_arguments(c);
855  pips_assert(gen_length(args) == 2, "2 args to assign");
856  expression e1 = EXPRESSION(CAR(args));
857  if (expression_reference_p(e1))
858  {
860  gen_recurse_stop(r1);
861  // deal with x = x
862  expression e2 = EXPRESSION(CAR(CDR(args)));
863  if (expression_reference_p(e2))
864  {
866  if (reference_variable(r1) == reference_variable(r2) &&
867  reference_indices(r1) == NIL &&
868  reference_indices(r2) == NIL)
869  return false;
870  }
871  }
872  }
873  return true;
874 }
void gen_recurse_stop(void *obj)
Tells the recursion not to go in this object.
Definition: genClib.c:3251
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define ENTITY_ASSIGN_P(e)

References call_arguments, call_function, CAR, CDR, ENTITY_ASSIGN_P, EXPRESSION, expression_reference(), expression_reference_p(), gen_length(), gen_recurse_stop(), NIL, pips_assert, reference_indices, and reference_variable.

Referenced by freia_shuffle_move_forward().

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

◆ fcs_count()

static bool fcs_count ( statement  s,
fcs_ctx ctx 
)
static

Definition at line 142 of file freia_transformations.c.

143 {
144  if (!statement_call_p(s))
145  {
146  ctx->bad_stuff = true;
147  gen_recurse_stop(NULL);
148  }
149  else
150  {
152  if (c)
153  {
154  const char* called = entity_local_name(call_function(c));
155  // could be: dilate + inf + vol or erode + sup + vol
156  if (same_string_p(called, AIPO "erode_8c") ||
157  same_string_p(called, AIPO "erode_6c") ||
158  same_string_p(called, AIPO "dilate_8c") ||
159  same_string_p(called, AIPO "dilate_6c"))
160  ctx->morpho++;
161  else if (same_string_p(called, AIPO "inf") ||
162  same_string_p(called, AIPO "sup"))
163  ctx->comp++;
164  else if (same_string_p(called, AIPO "global_vol"))
165  ctx->vol++;
166  // else { // should do more filtering!
167  // ctx->bad_stuff = true;
168  // gen_recurse_stop(NULL);
169  // }
170  }
171  }
172  return false;
173 }
call freia_statement_to_call(const statement s)
return the actual function call from a statement, dealing with assign and returns....
Definition: freia-utils.c:973
#define AIPO
Definition: freia.h:51
bool statement_call_p(statement)
Definition: statement.c:364
#define same_string_p(s1, s2)
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

References AIPO, fcs_ctx::bad_stuff, call_function, fcs_ctx::comp, entity_local_name(), freia_statement_to_call(), gen_recurse_stop(), fcs_ctx::morpho, same_string_p, statement_call_p(), and fcs_ctx::vol.

Referenced by freia_convergence_sequence_p().

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

◆ freia_convergence_sequence_p()

static bool freia_convergence_sequence_p ( sequence  sq)
static
Returns
whether sq contains freia simple calls to E/D, </>, vol, = this is rather an over approximation of whether it is a convergence sequence, should be refined...

Definition at line 179 of file freia_transformations.c.

180 {
181  fcs_ctx ctx = { 0, 0, 0, false };
183  return ctx.morpho==1 && ctx.comp==1 && ctx.vol==1 && !ctx.bad_stuff;
184 }
static bool fcs_count(statement s, fcs_ctx *ctx)
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
Definition: genC.h:285
void gen_null2(__attribute__((unused)) void *u1, __attribute__((unused)) void *u2)
idem with 2 args, to please overpeaky compiler checks
Definition: genClib.c:2758
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
Definition: freia.c:53

References fcs_ctx::bad_stuff, fcs_ctx::comp, fcs_count(), gen_context_recurse, gen_null2(), fcs_ctx::morpho, statement_domain, and fcs_ctx::vol.

Referenced by maybe_unroll_while_rwt().

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

◆ freia_reduction_variable()

static entity freia_reduction_variable ( const statement  s)
static

return the freia reduction entity, or NULL if it does not apply

Definition at line 335 of file freia_transformations.c.

336 {
338  {
339  const call c = freia_statement_to_call(s);
340  const string called = (const string) entity_local_name(call_function(c));
341  if (same_string_p(called, AIPO "global_min") ||
342  same_string_p(called, AIPO "global_max") ||
343  same_string_p(called, AIPO "global_min_coord") ||
344  same_string_p(called, AIPO "global_max_coord") ||
345  same_string_p(called, AIPO "global_vol"))
346  {
347  const expression last = EXPRESSION(CAR(gen_last(call_arguments(c))));
348  // should be a call to "&" operator
349  if (expression_address_of_p(last))
350  {
351  const expression arg =
354  return expression_variable(arg);
355  }
356  }
357  }
358  // not found!
359  return NULL;
360 }
bool freia_statement_aipo_call_p(const statement s)
returns whether the statement is a FREIA call.
Definition: freia-utils.c:814
list gen_last(list l)
Return the last element of a list.
Definition: list.c:578
char * string
STRING.
Definition: newgen_types.h:39
bool expression_address_of_p(expression e)
Definition: expression.c:420
entity expression_variable(expression e)
Definition: expression.c:532
#define syntax_reference_p(x)
Definition: ri.h:2728
#define expression_syntax(x)
Definition: ri.h:1247

References AIPO, call_arguments, call_function, CAR, entity_local_name(), EXPRESSION, expression_address_of_p(), expression_call(), expression_syntax, expression_variable(), freia_statement_aipo_call_p(), freia_statement_to_call(), gen_last(), same_string_p, and syntax_reference_p.

Referenced by sww_seq_rwt().

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

◆ freia_remove_scalar_ww_deps()

bool freia_remove_scalar_ww_deps ( const string  module)
Parameters
moduleodule

Definition at line 430 of file freia_transformations.c.

431 {
432  debug_on("PIPS_HWAC_DEBUG_LEVEL");
433  pips_debug(1, "considering module %s\n", module);
434 
435  // else do the stuff
437  (statement) db_get_memory_resource(DBR_CODE, module, true);
440 
441  // do the job
442  bool changed = false;
443  gen_context_recurse(mod_stat, &changed,
445 
446  // update database if changed
447  if (changed)
448  // stmt_renumber(mod_stat); module_reorder(mod_stat);
450 
453  debug_off();
454  return true;
455 }
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
static void sww_seq_rwt(const sequence sq, bool *changed)
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
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
bool gen_true2(__attribute__((unused)) gen_chunk *u1, __attribute__((unused)) void *u2)
Definition: genClib.c:2785
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
static statement mod_stat
We want to keep track of the current statement inside the recurse.
Definition: impact_check.c:41
#define debug_on(env)
Definition: misc-local.h:157
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define debug_off()
Definition: misc-local.h:160
static char * module
Definition: pips.c:74
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
#define sequence_domain
newgen_reference_domain_defined
Definition: ri.h:346

References db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, gen_context_recurse, gen_true2(), mod_stat, module, module_name_to_entity(), pips_debug, reset_current_module_entity(), reset_current_module_statement(), sequence_domain, set_current_module_entity(), set_current_module_statement(), and sww_seq_rwt().

+ Here is the call graph for this function:

◆ freia_shuffle_move_forward()

void freia_shuffle_move_forward ( statement  s)

Definition at line 876 of file freia_transformations.c.

877 {
878  shuffle_context ctx = { 0, 0, NIL, NULL };
879  // forward substitude simple image assignments
881  // remove image assignments that are not used
882  // TODO ??? initializations...
883  // count image read references
884  hash_table reads = hash_table_make(hash_pointer, 100); // entity -> _int
885  gen_context_multi_recurse(s, reads,
888  NULL);
889  // cleanup assignments of unused images
890  FOREACH(statement, sa, ctx.assigns)
891  {
892  // be safe
893  pips_assert(statement_call_p(sa), "statement is a call");
894  call c = statement_call(sa);
895  pips_assert(ENTITY_ASSIGN_P(call_function(c)), "call is assign");
896  list args = call_arguments(c);
897  pips_assert(gen_length(args) == 2, "2 args to assign");
898  expression e1 = EXPRESSION(CAR(args));
899  pips_assert(expression_reference_p(e1), "expr is reference");
901  entity img = reference_variable(r);
902  pips_assert(reference_indices(r) == NIL, "no array reference");
903  pips_assert(freia_image_variable_p(img), "reference an image");
904 
905  // cleanup unused images
906  if (!hash_defined_p(reads, img))
907  {
908  // remove assignment of unused image pointer
911  // coldly cleanup corresponding effects... (free effects not needed?)
914  // ??? what about proper effects?
915  // stats
916  ctx.removed ++;
917  }
918  }
919  hash_table_free(reads), reads = NULL;
920 
921  // be verbose because I'm not sure of the pass
922  if (ctx.changed != 0 || ctx.removed != 0)
923  pips_user_warning("%d subsitution(s) and %d assignment(s) removed",
924  ctx.changed, ctx.removed);
925 
926  gen_free_list(ctx.assigns), ctx.assigns = NIL;
927 }
void free_instruction(instruction p)
Definition: ri.c:1118
effects delete_cumulated_rw_effects(statement)
void store_cumulated_rw_effects_list(statement, list)
bool freia_image_variable_p(const entity var)
rather approximative?
Definition: freia-utils.c:768
static bool call_count_flt(call c, _UNUSED_ hash_table counts)
static void ref_count_rwt(reference r, hash_table counts)
static void seq_rwt(sequence sq, shuffle_context *ctx)
void gen_context_multi_recurse(void *o, void *context,...)
Multi-recursion with context function visitor.
Definition: genClib.c:3373
instruction make_continue_instruction()
Creates a CONTINUE instruction, that is the FORTRAN nop, the ";" in C or the "pass" in Python for exa...
Definition: instruction.c:79
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#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
call statement_call(statement)
Get the call of a statement.
Definition: statement.c:1406
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
bool hash_defined_p(const hash_table htp, const void *key)
true if key has e value in htp.
Definition: hash.c:484
#define pips_user_warning
Definition: misc-local.h:146
@ hash_pointer
Definition: newgen_hash.h:32
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
#define reference_domain
newgen_range_domain_defined
Definition: ri.h:338
#define statement_instruction(x)
Definition: ri.h:2458

References shuffle_context::assigns, call_arguments, call_count_flt(), call_domain, call_function, CAR, shuffle_context::changed, delete_cumulated_rw_effects(), ENTITY_ASSIGN_P, EXPRESSION, expression_reference(), expression_reference_p(), FOREACH, free_instruction(), freia_image_variable_p(), gen_context_multi_recurse(), gen_context_recurse, gen_free_list(), gen_length(), gen_null2(), gen_true2(), hash_defined_p(), hash_pointer, hash_table_free(), hash_table_make(), make_continue_instruction(), NIL, pips_assert, pips_user_warning, ref_count_rwt(), reference_domain, reference_indices, reference_variable, shuffle_context::removed, seq_rwt(), sequence_domain, statement_call(), statement_call_p(), statement_instruction, and store_cumulated_rw_effects_list().

Referenced by freia_compile().

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

◆ freia_unroll_while()

bool freia_unroll_while ( const string  module)

freia_transformations.c

Parameters
moduleodule

Definition at line 269 of file freia_transformations.c.

270 {
271  // sanity check
272  int factor = get_int_property(spoc_depth_prop);
273  if (factor<=1)
274  {
275  pips_user_warning("cannot unroll with factor=%d\n", factor);
276  return true;
277  }
278 
279  // else, do the job
280  debug_on("PIPS_HWAC_DEBUG_LEVEL");
281  pips_debug(1, "considering module %s\n", module);
282 
283  // else do the stuff
285  (statement) db_get_memory_resource(DBR_CODE, module, true);
288 
289  // do the job
290  bool changed = freia_unroll_while_for_spoc(mod_stat);
291 
292  // update if changed
293  if (changed)
294  {
298  }
299 
300  // cleanup
303  debug_off();
304  return true;
305 }
int get_int_property(const string)
#define spoc_depth_prop
Definition: freia_spoc.h:185
static bool freia_unroll_while_for_spoc(statement s)
static void stmt_renumber(statement s)
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244

References db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, freia_unroll_while_for_spoc(), get_int_property(), mod_stat, module, module_name_to_entity(), module_reorder(), pips_debug, pips_user_warning, reset_current_module_entity(), reset_current_module_statement(), set_current_module_entity(), set_current_module_statement(), spoc_depth_prop, and stmt_renumber().

+ Here is the call graph for this function:

◆ freia_unroll_while_for_spoc()

static bool freia_unroll_while_for_spoc ( statement  s)
static

Definition at line 261 of file freia_transformations.c.

262 {
263  bool changed = false;
264  gen_context_recurse(s, &changed,
266  return changed;
267 }
static void maybe_unroll_while_rwt(whileloop wl, bool *changed)
#define whileloop_domain
newgen_variable_domain_defined
Definition: ri.h:466

References gen_context_recurse, gen_true2(), maybe_unroll_while_rwt(), and whileloop_domain.

Referenced by freia_unroll_while().

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

◆ maybe_unroll_while_rwt()

static void maybe_unroll_while_rwt ( whileloop  wl,
bool changed 
)
static

Definition at line 201 of file freia_transformations.c.

202 {
204  {
207  {
208  // unroll!
209  int factor = get_int_property(spoc_depth_prop);
210  pips_assert("some unrolling factor", factor>0);
211  list ol = sequence_statements(sq);
212 
213  // sorry, just a hack to avoid a precise pattern matching
214  statement first = STATEMENT(CAR(ol));
215  pips_assert("s is an assignement", statement_call_p(first));
216  gen_remove_once(&ol, first);
217  list col = gen_copy_seq(ol), nl = NIL;
218  list lass = call_arguments(statement_call(first));
219  entity
220  previous = expression_variable(EXPRESSION(CAR(lass))),
222 
223  // cleanup vol from col
225  FOREACH(statement, s, col)
226  {
229  AIPO "global_vol"))
230  {
231  gen_remove_once(&col, s);
232  vols = copy_statement(s);
233  break;
234  }
235  }
236  pips_assert("vol statement found", vols!=statement_undefined);
237 
238  // do factor-1
239  while (--factor)
240  nl = gen_nconc(gen_full_copy_list(col), nl);
241 
242  // compute "previous" volume for comparison
243  substitute_reference_variable(vols, current, previous);
244 
245  // swith off "register" on previous, if need be...
246  variable v = type_variable(entity_type(previous));
248 
249  // then reuse initial list for the last one
250  sequence_statements(sq) = gen_nconc(nl, CONS(statement, vols, ol));
251 
252  // cleanup temporary list
254 
255  // must renumber...
256  *changed = true;
257  }
258  }
259 }
statement copy_statement(statement p)
STATEMENT.
Definition: ri.c:2186
static void substitute_reference_variable(statement s, entity ovar, entity nvar)
static list remove_register(list lq)
remove "register" qualifier from qualifier list
static bool freia_convergence_sequence_p(sequence sq)
void gen_remove_once(list *pl, const void *o)
Remove the first occurence of o in list pl:
Definition: list.c:691
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
#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
list gen_full_copy_list(list l)
Copy a list structure with element copy.
Definition: list.c:535
sequence statement_sequence(statement)
Get the sequence of a statement sequence.
Definition: statement.c:1328
bool statement_sequence_p(statement)
Statement classes induced from instruction type.
Definition: statement.c:335
#define type_variable(x)
Definition: ri.h:2949
#define sequence_statements(x)
Definition: ri.h:2360
#define variable_qualifiers(x)
Definition: ri.h:3124
#define whileloop_body(x)
Definition: ri.h:3162
#define entity_type(x)
Definition: ri.h:2792
#define statement_undefined
Definition: ri.h:2419
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
static size_t current
Definition: string.c:115

References AIPO, call_arguments, call_function, CAR, CDR, CONS, copy_statement(), current, entity_local_name(), entity_type, EXPRESSION, expression_variable(), FOREACH, freia_convergence_sequence_p(), freia_statement_to_call(), gen_copy_seq(), gen_free_list(), gen_full_copy_list(), gen_nconc(), gen_remove_once(), get_int_property(), NIL, pips_assert, remove_register(), same_string_p, sequence_statements, spoc_depth_prop, STATEMENT, statement_call(), statement_call_p(), statement_sequence(), statement_sequence_p(), statement_undefined, substitute_reference_variable(), type_variable, variable_qualifiers, and whileloop_body.

Referenced by freia_unroll_while_for_spoc().

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

◆ pointer_candidate_p()

static bool pointer_candidate_p ( entity  var)
static

Definition at line 501 of file freia_transformations.c.

502 {
503  // other checks?
504  pips_debug(5, "entity %s %d\n", entity_name(var), entity_pointer_p(var));
505  return entity_pointer_p(var);
506 }
bool entity_pointer_p(entity e)
Definition: entity.c:745
#define entity_name(x)
Definition: ri.h:2790

References entity_name, entity_pointer_p(), and pips_debug.

Referenced by remove_simple_scalar_pointers(), and rssp_ref().

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

◆ ref_count_rwt()

static void ref_count_rwt ( reference  r,
hash_table  counts 
)
static

Definition at line 834 of file freia_transformations.c.

835 {
836  entity v = reference_variable(r);
837  if (freia_image_variable_p(v))
838  {
839  if (hash_defined_p(counts, v))
840  {
841  _int count = (_int) hash_get(counts, v) + 1;
842  hash_update(counts, v, (void *) count);
843  }
844  else
845  hash_put(counts, v, (void *) (_int) 1);
846  }
847 }
static int count
Definition: SDG.c:519
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
void hash_put(hash_table htp, const void *key, const void *val)
This functions stores a couple (key,val) in the hash table pointed to by htp.
Definition: hash.c:364
void hash_update(hash_table htp, const void *key, const void *val)
update key->val in htp, that MUST be pre-existent.
Definition: hash.c:491
intptr_t _int
_INT
Definition: newgen_types.h:53

References count, freia_image_variable_p(), hash_defined_p(), hash_get(), hash_put(), hash_update(), and reference_variable.

Referenced by freia_shuffle_move_forward().

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

◆ ref_rwt()

static void ref_rwt ( reference  r,
subs_ctx ctx 
)
static

Definition at line 189 of file freia_transformations.c.

190 {
191  if (reference_variable(r)==ctx->ovar)
192  reference_variable(r)=ctx->nvar;
193 }

References subs_ctx::nvar, subs_ctx::ovar, and reference_variable.

Referenced by substitute_reference_variable().

+ Here is the caller graph for this function:

◆ remove_register()

static list remove_register ( list  lq)
static

remove "register" qualifier from qualifier list

Definition at line 55 of file freia_transformations.c.

56 {
57  FOREACH(qualifier, q, lq)
58  {
59  if (qualifier_register_p(q))
60  {
61  gen_remove_once(&lq, q);
62  // register may be there once
63  return lq;
64  }
65  }
66  return lq;
67 }
#define qualifier_register_p(x)
Definition: ri.h:2185

References FOREACH, gen_remove_once(), and qualifier_register_p.

Referenced by maybe_unroll_while_rwt(), and sww_seq_rwt().

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

◆ remove_simple_scalar_pointers()

bool remove_simple_scalar_pointers ( const string  module)
Parameters
moduleodule

Definition at line 584 of file freia_transformations.c.

585 {
586  debug_on("PIPS_HWAC_DEBUG_LEVEL");
587  pips_debug(1, "considering module %s\n", module);
588 
589  // else do the stuff
591  (statement) db_get_memory_resource(DBR_CODE, module, true);
594 
595  rssp_ctx ctx;
601 
602  // get candidates
604  {
605  if (pointer_candidate_p(var))
606  {
607  set_add_element(ctx.candidates, ctx.candidates, var);
609  {
611  entity v2 = address_of_scalar(e);
612  if (v2)
613  {
614  hash_put(ctx.points_to, var, v2);
615  hash_put(ctx.defined, var, expression_call(e));
616  }
617  }
618  }
619  }
620 
621 
622  // check condition
624  (mod_stat, &ctx,
626  // ignore sizeof
628  NULL);
629 
630  bool changed = false;
631  // apply transformation
632  SET_FOREACH(entity, var, ctx.candidates)
633  {
634  pips_debug(2, "considering entity %s inv=%d dr=%d def=%d pt=%d\n",
635  entity_name(var), set_belong_p(ctx.invalidated, var),
636  hash_defined_p(ctx.dereferenced, var),
637  hash_defined_p(ctx.defined, var),
638  hash_defined_p(ctx.points_to, var));
639 
640  if (!set_belong_p(ctx.invalidated, var) &&
641  hash_defined_p(ctx.dereferenced, var) &&
642  hash_defined_p(ctx.defined, var) &&
643  hash_defined_p(ctx.points_to, var))
644  {
645  changed = true;
646  // replace use
647  expression deref = (expression) hash_get(ctx.dereferenced, var);
649  (make_reference((entity) hash_get(ctx.points_to, var), NIL));
650  // drop definition
651  call definition = (call) hash_get(ctx.defined, var);
652  gen_free_list(call_arguments(definition)),
653  call_arguments(definition) = NIL;
655  // declaration cleanup?
656  }
657  }
658 
659  // result
660  if (changed)
662 
663  // cleanup
664  set_free(ctx.candidates);
665  set_free(ctx.invalidated);
671  debug_off();
672 
673  return true;
674 }
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
syntax make_syntax_reference(reference _field_)
Definition: ri.c:2494
struct _newgen_struct_expression_ * expression
Definition: alias_private.h:21
static void rssp_ref(reference r, rssp_ctx *ctx)
static entity address_of_scalar(expression e)
"&v"? return v, else return NULL
static bool pointer_candidate_p(entity var)
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
bool gen_false(__attribute__((unused)) gen_chunk *unused)
Return false and ignore the argument.
Definition: genClib.c:2796
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
#define SET_FOREACH(type_name, the_item, the_set)
enumerate set elements in their internal order.
Definition: newgen_set.h:78
void set_free(set)
Definition: set.c:332
bool set_belong_p(const set, const void *)
Definition: set.c:194
@ set_pointer
Definition: newgen_set.h:44
set set_make(set_type)
Create an empty set of any type but hash_private.
Definition: set.c:102
set set_add_element(set, const set, const void *)
Definition: set.c:152
#define entity_declarations(e)
MISC: newgen shorthands.
entity make_integer_constant_entity(_int)
entity make_integer_constant_entity(int c) make entity for integer constant c
Definition: variable.c:1345
#define sizeofexpression_domain
newgen_sequence_domain_defined
Definition: ri.h:354
struct _newgen_struct_call_ * call
Definition: ri.h:63
#define value_expression_p(x)
Definition: ri.h:3080
#define value_expression(x)
Definition: ri.h:3082
#define entity_initial(x)
Definition: ri.h:2796
hash_table points_to
hash_table dereferenced
hash_table defined

References address_of_scalar(), call_arguments, call_function, rssp_ctx::candidates, db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, rssp_ctx::defined, rssp_ctx::dereferenced, entity_declarations, entity_initial, entity_name, expression_call(), expression_syntax, FOREACH, gen_context_multi_recurse(), gen_false(), gen_free_list(), gen_null(), gen_true(), get_current_module_entity(), hash_defined_p(), hash_get(), hash_pointer, hash_put(), hash_table_free(), hash_table_make(), rssp_ctx::invalidated, make_integer_constant_entity(), make_reference(), make_syntax_reference(), mod_stat, module, module_name_to_entity(), NIL, pips_debug, pointer_candidate_p(), rssp_ctx::points_to, reference_domain, reset_current_module_entity(), reset_current_module_statement(), rssp_ref(), set_add_element(), set_belong_p(), set_current_module_entity(), set_current_module_statement(), SET_FOREACH, set_free(), set_make(), set_pointer, sizeofexpression_domain, value_expression, and value_expression_p.

+ Here is the call graph for this function:

◆ rssp_ref()

static void rssp_ref ( reference  r,
rssp_ctx ctx 
)
static

Definition at line 508 of file freia_transformations.c.

509 {
510  string what = "unknown";
511  entity var = reference_variable(r);
512  pips_debug(8, "reference %p to %s\n", r, entity_name(var));
513  if (pointer_candidate_p(var) && !reference_indices(r))
514  set_add_element(ctx->candidates, ctx->candidates, var);
515  if (set_belong_p(ctx->candidates, var))
516  {
518  if (enc && expression_reference_p(enc) && expression_reference(enc)==r)
519  {
520  call called = (call) gen_get_ancestor(call_domain, enc);
521 
522  pips_debug(8, "called=%p %s\n", called, called?
523  entity_name(call_function(called)): "<nope>");
524 
525  if (called &&
526  ENTITY_ASSIGN_P(call_function(called)) &&
527  EXPRESSION(CAR(call_arguments(called)))==enc)
528  {
529  // is it a definition: var = ...
530  list args = call_arguments(called);
531  pips_assert("2 args to assign", gen_length(args)==2);
532  entity v2 =
534  if (v2)
535  {
536  if (!hash_defined_p(ctx->points_to, var))
537  hash_put(ctx->points_to, var, v2),
538  hash_put(ctx->defined, var, called),
539  what="! var = &YYY";
540  else
541  set_add_element(ctx->invalidated, ctx->invalidated, var),
542  what="already defined";
543  }
544  else
545  set_add_element(ctx->invalidated, ctx->invalidated, var),
546  what="no v2";
547  }
548  else if (called && ENTITY_DEREFERENCING_P(call_function(called)))
549  {
550  // *var ...
551  call upper = (call) gen_get_ancestor(call_domain, called);
552  expression first = (upper && call_arguments(upper))?
553  EXPRESSION(CAR(call_arguments(upper))): NULL;
554 
555  pips_debug(8, "upper=%p first=%p %s\n", upper, first, upper?
556  entity_name(call_function(upper)): "<nope>");
557 
558  if (upper && first &&
559  ENTITY_ASSIGN_P(call_function(upper)) &&
560  expression_call_p(first) &&
561  expression_call(first) == called &&
562  !hash_defined_p(ctx->dereferenced, var))
563  // *var = XXX
564  hash_put(ctx->dereferenced, var, first),
565  what="! *var = XXX";
566  else
567  set_add_element(ctx->invalidated, ctx->invalidated, var),
568  what="not *var = ...";
569  }
570  else
571  set_add_element(ctx->invalidated, ctx->invalidated, var),
572  what="not = or *";
573  }
574  else
575  set_add_element(ctx->invalidated, ctx->invalidated, var),
576  what="not enc";
577  }
578  else
579  what="not candidate";
580  pips_debug(5, "candidate %s: %s\n", entity_name(var), what);
581  //return true;
582 }
gen_chunk * gen_get_ancestor(int, const void *)
return the first ancestor object found of the given type.
Definition: genClib.c:3560
#define ENTITY_DEREFERENCING_P(e)
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154

References address_of_scalar(), call_arguments, call_domain, call_function, rssp_ctx::candidates, CAR, CDR, rssp_ctx::defined, rssp_ctx::dereferenced, ENTITY_ASSIGN_P, ENTITY_DEREFERENCING_P, entity_name, EXPRESSION, expression_call(), expression_call_p(), expression_domain, expression_reference(), expression_reference_p(), gen_get_ancestor(), gen_length(), hash_defined_p(), hash_put(), rssp_ctx::invalidated, pips_assert, pips_debug, pointer_candidate_p(), rssp_ctx::points_to, reference_indices, reference_variable, set_add_element(), and set_belong_p().

Referenced by remove_simple_scalar_pointers().

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

◆ seq_rwt()

static void seq_rwt ( sequence  sq,
shuffle_context ctx 
)
static

Definition at line 748 of file freia_transformations.c.

749 {
750  ctx->equal = hash_table_make(hash_pointer, 10);
751 
753  {
754  if (statement_call_p(s))
755  {
756  call c = statement_call(s);
757  list args = call_arguments(c);
759  {
760  // ... = ...
761  pips_assert("2 arguments", gen_length(args)==2);
762  expression e1 = EXPRESSION(CAR(args)), e2 = EXPRESSION(CAR(CDR(args)));
763  if (expression_reference_p(e1))
764  {
765  entity v1 = expression_variable(e1);
766  if (freia_image_variable_p(v1))
767  {
768  // is the second image an image?
769  entity v2 = NULL;
770  if (expression_reference_p(e2))
771  {
772  v2 = expression_variable(e2);
773  if (!freia_image_variable_p(v2))
774  v2 = NULL;
775  }
776 
777  // img = ...
778  // cleanup all equalities with img, but not on img=img
779  if (v1 != v2)
780  {
781  list delete = CONS(entity, v1, NIL);
782  HASH_FOREACH(entity, k, entity, v, ctx->equal)
783  // maybe could replace by other equal if any?
784  if (v == v1)
785  delete = CONS(entity, k, delete);
786  FOREACH(entity, e, delete)
787  (void) hash_del(ctx->equal, e);
788  gen_free_list(delete), delete = NIL;
789  }
790 
791  // image assignement
792  if (v2 != NULL)
793  {
794  // img1 = img2
795  ctx->assigns = CONS(statement, s, ctx->assigns);
796  if (v1 != v2) // distinct images
797  {
798  // point to prior image if any
799  if (hash_defined_p(ctx->equal, v2))
800  {
801  entity end = hash_get(ctx->equal, v2);
803  hash_put(ctx->equal, v1, end);
804  }
805  else
806  hash_put(ctx->equal, v1, v2);
807  }
808  // else skip silently "img = img;"
809  }
810  // else no image on rhs
811  }
812  else // not image assignment
813  {
815  }
816  }
817  }
818  else // a call, but not an assignment
819  {
821  }
822  }
823  else // not a call
824  {
825  // hmmm... safe option for now, cleanup current equalities
826  // ??? could keep those on which there is no effect?
827  hash_table_clear(ctx->equal);
828  }
829  }
830  hash_table_free(ctx->equal); ctx->equal = NULL;
831 }
static void substitute_image_occurrences(void *s, shuffle_context *ctx)
if(!(yy_init))
Definition: genread_lex.c:1029
char end
Definition: gtk_status.c:82
void * hash_del(hash_table htp, const void *key)
this function removes from the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:439
void hash_table_clear(hash_table htp)
Clears all entries of a hash table HTP.
Definition: hash.c:305
#define HASH_FOREACH(key_type, k, value_type, v, ht)
Definition: newgen_hash.h:71

References shuffle_context::assigns, call_arguments, call_function, CAR, CDR, CONS, end, ENTITY_ASSIGN_P, shuffle_context::equal, EXPRESSION, expression_reference(), expression_reference_p(), expression_variable(), FOREACH, freia_image_variable_p(), gen_free_list(), gen_length(), hash_defined_p(), hash_del(), HASH_FOREACH, hash_get(), hash_pointer, hash_put(), hash_table_clear(), hash_table_free(), hash_table_make(), NIL, pips_assert, reference_variable, sequence_statements, statement_call(), statement_call_p(), and substitute_image_occurrences().

Referenced by freia_shuffle_move_forward().

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

◆ sio_call_flt()

static bool sio_call_flt ( call  c,
_UNUSED_ shuffle_context ctx 
)
static

Definition at line 712 of file freia_transformations.c.

713 {
714  entity f = call_function(c);
715  return ENTITY_ASSIGN_P(f) || entity_update_p(f) ||
716  hwac_freia_api(entity_local_name(f)) != NULL ||
717  // hmmm... also freia_common_ functions
718  starts_with(entity_local_name(f), "freia_common_");
719 }
const freia_api_t * hwac_freia_api(const char *function)
freia-utils.c
Definition: freia-utils.c:455
#define starts_with(s1, s2)
#define entity_update_p(e)
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15

References call_function, ENTITY_ASSIGN_P, entity_local_name(), entity_update_p, f(), hwac_freia_api(), and starts_with.

Referenced by substitute_image_occurrences().

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

◆ sio_ref_rwt()

static void sio_ref_rwt ( reference  r,
shuffle_context ctx 
)
static

Definition at line 722 of file freia_transformations.c.

723 {
724  if (reference_indices(r) != NIL)
725  return;
726  entity v = reference_variable(r);
727  if (hash_defined_p(ctx->equal, v))
728  {
729  reference_variable(r) = hash_get(ctx->equal, v);
730  ctx->changed++;
731  }
732 }

References shuffle_context::changed, shuffle_context::equal, hash_defined_p(), hash_get(), NIL, reference_indices, and reference_variable.

Referenced by substitute_image_occurrences().

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

◆ sr_flt()

static bool sr_flt ( statement  s,
int number 
)
static

Definition at line 74 of file freia_transformations.c.

75 {
78  // it seems that sequences are expected not to have a number
79  // just in case, force the property
82  // just add a number if none are available?
83  // otherwise, the initial number is kept
84  statement_number(s) = (*number)++;
85  return true;
86 }
#define STATEMENT_NUMBER_UNDEFINED
default values
#define instruction_sequence_p(x)
Definition: ri.h:1512
#define statement_number(x)
Definition: ri.h:2452

References instruction_sequence_p, statement_instruction, statement_number, and STATEMENT_NUMBER_UNDEFINED.

Referenced by stmt_renumber().

+ Here is the caller graph for this function:

◆ stmt_renumber()

static void stmt_renumber ( statement  s)
static

Definition at line 88 of file freia_transformations.c.

89 {
90  int number=1;
92 }
static bool sr_flt(statement s, int *number)

References gen_context_recurse, gen_null2(), sr_flt(), and statement_domain.

Referenced by freia_unroll_while().

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

◆ substitute_image_occurrences()

static void substitute_image_occurrences ( void *  s,
shuffle_context ctx 
)
static

Definition at line 735 of file freia_transformations.c.

736 {
740  NULL);
741 }
static void sio_ref_rwt(reference r, shuffle_context *ctx)
static bool sio_call_flt(call c, _UNUSED_ shuffle_context *ctx)

References call_domain, gen_context_multi_recurse(), gen_null(), gen_true(), reference_domain, sio_call_flt(), and sio_ref_rwt().

Referenced by seq_rwt().

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

◆ substitute_reference_variable()

static void substitute_reference_variable ( statement  s,
entity  ovar,
entity  nvar 
)
static

Definition at line 195 of file freia_transformations.c.

196 {
197  subs_ctx ctx = { ovar, nvar };
199 }
static void ref_rwt(reference r, subs_ctx *ctx)
util defined somewhere ??????

References gen_context_recurse, gen_true2(), ref_rwt(), and reference_domain.

Referenced by maybe_unroll_while_rwt().

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

◆ sww_seq_rwt()

static void sww_seq_rwt ( const sequence  sq,
bool changed 
)
static

Definition at line 362 of file freia_transformations.c.

363 {
364  // current status of search
365  statement previous_reduction = NULL;
366  entity previous_variable = NULL;
367  statement assignment = NULL;
368  entity assigned = NULL;
369 
370  // this is a partial O(n) implementation
371  // beware that we may have VERY LONG sequences...
373  {
374  bool tocheck = true;
376  if (red)
377  {
378  if (previous_reduction && assignment && red==previous_variable)
379  {
380  // matched!
381  // replace variable in first reduction
382  hash_table replacements = hash_table_make(hash_pointer, 0);
383  hash_put(replacements, previous_variable, assigned);
384  replace_entities(previous_reduction, replacements);
385  hash_table_free(replacements);
386  // and now useless remove assignment
389  // make assigned NOT a register... just in case
390  variable v = type_variable(entity_type(assigned));
392  // we did something
393  *changed = true;
394  }
395 
396  // restart current status with new found reduction
397  previous_reduction = s;
398  previous_variable = red;
399  assignment = NULL;
400  assigned = NULL;
401  tocheck = false;
402  }
403 
404  // detect reduction variable assignment
405  if (previous_reduction && !assignment &&
407  {
409  expression e1 = EXPRESSION(CAR(args)), e2 = EXPRESSION(CAR(CDR(args)));
411  reference_variable(expression_reference(e2))==previous_variable)
412  {
413  assignment = s;
415  tocheck = false;
416  }
417  }
418 
419  if (tocheck && previous_variable && variable_is_used(s, previous_variable))
420  {
421  // full cleanup
422  previous_reduction = NULL;
423  previous_variable = NULL;
424  assignment = NULL;
425  assigned = NULL;
426  }
427  }
428 }
static entity freia_reduction_variable(const statement s)
return the freia reduction entity, or NULL if it does not apply
static bool variable_is_used(statement s, entity var)
void replace_entities(void *s, hash_table ht)
Recursively substitute a set of entities in a statement.
Definition: replace.c:91
bool instruction_assign_p(instruction i)
Test if an instruction is an assignment.
Definition: instruction.c:164
#define instruction_call(x)
Definition: ri.h:1529

References call_arguments, CAR, CDR, entity_type, EXPRESSION, expression_reference(), expression_reference_p(), FOREACH, free_instruction(), freia_reduction_variable(), hash_pointer, hash_put(), hash_table_free(), hash_table_make(), instruction_assign_p(), instruction_call, make_continue_instruction(), reference_variable, remove_register(), replace_entities(), sequence_statements, statement_instruction, type_variable, variable_is_used(), and variable_qualifiers.

Referenced by freia_remove_scalar_ww_deps().

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

◆ variable_is_used()

static bool variable_is_used ( statement  s,
entity  var 
)
static

Definition at line 111 of file freia_transformations.c.

112 {
113  vis_ctx ctx = { false, var };
115  return ctx.used;
116 }
static void vis_rwt(const reference r, vis_ctx *ctx)
look for a variable

References gen_context_recurse, gen_true2(), reference_domain, vis_ctx::used, and vis_rwt().

Referenced by sww_seq_rwt().

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

◆ vis_rwt()

static void vis_rwt ( const reference  r,
vis_ctx ctx 
)
static

Definition at line 102 of file freia_transformations.c.

103 {
104  if (reference_variable(r)==ctx->var)
105  {
106  ctx->used = true;
107  gen_recurse_stop(NULL);
108  }
109 }

References gen_recurse_stop(), reference_variable, vis_ctx::used, and vis_ctx::var.

Referenced by variable_is_used().

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