PIPS
delay.c File Reference
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "effects.h"
#include "resources.h"
#include "misc.h"
#include "ri-util.h"
#include "workspace-util.h"
#include "effects-util.h"
#include "pipsdbm.h"
#include "preprocessor.h"
#include "effects-generic.h"
#include "effects-convex.h"
#include "properties.h"
#include "callgraph.h"
#include "transformations.h"
#include "dg.h"
#include "graph.h"
#include "control.h"
#include "ricedg.h"
#include "effects-simple.h"
#include "accel-util.h"
+ Include dependency graph for delay.c:

Go to the source code of this file.

Data Structures

struct  conflict_t
 helper for do_recurse_statements_conflict_p More...
 
struct  context
 

Typedefs

typedef dg_arc_label arc_label
 
typedef dg_vertex_label vertex_label
 

Functions

static bool do_remove_preference (cell c)
 helper to transform preferences in references More...
 
void remove_preferences (void *obj)
 entry point to transform preferences in references More...
 
static bool simd_load_call_p (call c)
 
static bool simd_work_call_p (call c)
 
static bool simd_store_call_p (call c)
 
bool simd_load_stat_p (statement stat)
 
bool simd_work_stat_p (statement stat)
 
bool simd_store_stat_p (statement stat)
 
bool simd_dma_stat_p (statement stat)
 This function returns true if the statement is a simd loadsave statement. More...
 
bool simd_stat_p (statement stat)
 This function returns true if the statement is a simd statement. More...
 
static bool dma_conflict_p (conflict c)
 
static bool statements_conflict_p (statement s0, statement s1)
 checks if there exist a conflict between s0 and s1 according to the dependency graph More...
 
static bool statements_conflict_relaxed_p (statement s0, statement s1, bool load_p)
 same as statements_conflict_p but W-* conflicts are ignored if load_p, R-* conflicts are ignored if not load_p More...
 
static bool dma_statements_conflict_p (statement s0, statement s1)
 
static void do_recurse_statements_conflict_p (statement s, conflict_t *c)
 helper for recurse_statements_conflict_p More...
 
static bool recurse_statements_conflict_p (statement s, statement in)
 checks if there is a conflict between s and any statement in in More...
 
static context context_dup (context *c)
 
static void delay_communications_statement (statement, context *, list *block)
 
static void delay_communications_sequence (sequence s, context *c, list *block)
 
static void create_block_if_needed (statement *s, list **block)
 
static void insert_statement_in_block (statement s, statement inserted, bool before, list *block)
 
static void manage_conflicts (statement s, context *c, bool before, list *block)
 
static void delay_communications_call (statement s, context *c, list *block)
 
static void delay_communications_test (statement s, context *c, list *block)
 
static void delay_communications_anyloop (statement s, context *c, list *block)
 
static statement translate_arguments (call ca, statement s)
 
static void promote_local_entities (statement s, entity caller, statement caller_statement)
 if some local variables are going to be accessed inter procedurally, promote them to global variables More...
 
static void do_delay_communications_interprocedurally (call ca, context *c)
 
static void delay_communications_intraprocedurally (statement module_stat, context *c)
 transform each caller into a load / call /store sequence More...
 
static void delay_communications_interprocedurally (context *c)
 
static void delay_communications_init ()
 
static void delay_communications_reset ()
 
bool delay_load_communications (char *module_name)
 This phase looks for load or save statements that can be put out of the loop body and move these statements, if possible. More...
 
bool delay_load_communications_inter (char *module_name)
 
bool delay_load_communications_intra (char *module_name)
 
bool delay_store_communications (char *module_name)
 
bool delay_store_communications_inter (char *module_name)
 
bool delay_store_communications_intra (char *module_name)
 
static bool dmas_invert_p (statement s0, statement s1)
 
static void do_remove_redundant_communications_in_sequence (sequence s, bool *need_flatten)
 
static void select_independent_dmas (list *stats, statement parent)
 
static bool do_remove_redundant_communications_in_anyloop (statement parent, statement body)
 
static void do_remove_redundant_communications_in_loop (loop l, bool *need_flatten)
 
static void do_remove_redundant_communications_in_whileloop (whileloop l, bool *need_flatten)
 
static void do_remove_redundant_communications_in_forloop (forloop l, bool *need_flatten)
 
static bool remove_redundant_communications (statement s)
 
static bool delay_communications (const char *module_name)
 
bool delay_communications_inter (const char *module_name)
 
bool delay_communications_intra (const char *module_name)
 

Variables

static bool delay_communications_interprocedurally_p
 
static graph dependence_graph =graph_undefined
 
static bool __delay_communications_patch_properties
 

Detailed Description

Author
Serge Guelton serge.nosp@m..gue.nosp@m.lton@.nosp@m.enst.nosp@m.-bret.nosp@m.agne.nosp@m..fr
Version
Date
2010-12-15

Implementation of inter procedural load / store delaying

Definition in file delay.c.

Typedef Documentation

◆ arc_label

Definition at line 63 of file delay.c.

◆ vertex_label

Definition at line 64 of file delay.c.

Function Documentation

◆ context_dup()

static context context_dup ( context c)
static

Definition at line 262 of file delay.c.

262  {
263  // FI: Missing initializer... I add statement_undefined...
265  return cp;
266 }
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
#define statement_undefined
Definition: ri.h:2419
Pvecteur cp
pointeur sur l'egalite ou l'inegalite courante
Definition: sc_read.c:87
Definition: delay.c:253
entity caller
Definition: delay.c:258
bool need_flatten
Definition: delay.c:257
list stats
Definition: delay.c:255
bool result
Definition: delay.c:254
bool backward
Definition: delay.c:256

References context::backward, context::caller, cp, gen_copy_seq(), context::need_flatten, context::result, statement_undefined, and context::stats.

Referenced by delay_communications_anyloop(), and delay_communications_test().

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

◆ create_block_if_needed()

static void create_block_if_needed ( statement s,
list **  block 
)
static

Definition at line 279 of file delay.c.

279  {
280  if(!statement_block_p(*s) && !*block) {
281  pips_assert("declaration must be in a block\n",!declaration_statement_p(*s));
284  list tmp = CONS(STATEMENT,scopy,NIL);
287  *s=scopy;
288 
289  }
290 }
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
Definition: statement.c:597
instruction make_instruction_block(list statements)
Build an instruction block from a list of statements.
Definition: instruction.c:106
#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
sequence statement_sequence(statement)
Get the sequence of a statement sequence.
Definition: statement.c:1328
statement update_statement_instruction(statement, instruction)
Replace the instruction in statement s by instruction i.
Definition: statement.c:3039
bool declaration_statement_p(statement)
Had to be optimized according to Beatrice Creusillet.
Definition: statement.c:224
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define statement_block_p(stat)
#define instruction_undefined
Definition: ri.h:1454
#define sequence_statements(x)
Definition: ri.h:2360
#define statement_instruction(x)
Definition: ri.h:2458
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References CONS, declaration_statement_p(), instruction_to_statement(), instruction_undefined, make_instruction_block(), NIL, pips_assert, sequence_statements, STATEMENT, statement_block_p, statement_instruction, statement_sequence(), and update_statement_instruction().

Referenced by insert_statement_in_block().

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

◆ delay_communications()

static bool delay_communications ( const char *  module_name)
static

Get the code of the module.

clean badly generated sequences

Definition at line 924 of file delay.c.

925 {
926  /* Get the code of the module. */
928  statement module_stat = (statement)db_get_memory_resource(DBR_CODE, module_name, true);
930  set_current_module_statement( module_stat);
931  set_ordering_to_statement(module_stat);
932 
934  (statement_effects)db_get_memory_resource(DBR_PROPER_EFFECTS, module_name, true)
935  );
939  );
941 
942  debug_on("DELAY_COMMUNICATIONS_DEBUG_LEVEL");
943  bool need_flatten=
944  remove_redundant_communications(module_stat);
945 
946  /* clean badly generated sequences */
947  clean_up_sequences(module_stat);
948 
949  if(need_flatten)
951 
952 
953  pips_assert("Statement is consistent\n" , statement_consistent_p(module_stat));
954 
955  module_reorder(module_stat);
956  DB_PUT_MEMORY_RESOURCE(DBR_CODE, module_name, module_stat);
957  DB_PUT_MEMORY_RESOURCE(DBR_CALLEES, module_name, compute_callees(module_stat));
958 
959  debug_off();
961 
967 
968  return true;
969 }
bool statement_consistent_p(statement p)
Definition: ri.c:2195
static bool remove_redundant_communications(statement s)
Definition: delay.c:914
static graph dependence_graph
Definition: delay.c:93
void remove_preferences(void *obj)
entry point to transform preferences in references
Definition: delay.c:89
callees compute_callees(const statement stat)
Recompute the callees of a module statement.
Definition: callgraph.c:355
bool clean_up_sequences(statement s)
Recursively clean up the statement sequences by fusing them if possible and by removing useless one.
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
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)
statement_effects get_proper_rw_effects(void)
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
bool statement_flatten_declarations(entity module, statement s)
flatten_code.c
Definition: flatten_code.c:509
struct _newgen_struct_graph_ * graph
Definition: graph.h:31
#define graph_undefined
Definition: graph.h:60
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
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
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 module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479

References clean_up_sequences(), compute_callees(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, dependence_graph, get_proper_rw_effects(), graph_undefined, module, module_name(), module_name_to_entity(), module_reorder(), pips_assert, remove_preferences(), remove_redundant_communications(), 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(), statement_consistent_p(), and statement_flatten_declarations().

Referenced by delay_communications_inter(), and delay_communications_intra().

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

◆ delay_communications_anyloop()

static void delay_communications_anyloop ( statement  s,
context c,
list block 
)
static

first step is to check conflict with the head

then we check if there is a conflict inside the loop. In that case better insert before the loop than inside

then we propagate the dma inside the body

then we check for conflicts with indices or over iterations

if statements have been moved outside the loop then we (may) need to flatten

Definition at line 407 of file delay.c.

407  {
409  if(statement_loop_p(s)) body =loop_body(statement_loop(s));
410  else if(statement_forloop_p(s)) body =forloop_body(statement_forloop(s));
412  pips_assert("all loops have body\n",!statement_undefined_p(s));
413 
414  /* first step is to check conflict with the head */
416  /* then we check if there is a conflict inside the loop.
417  * In that case better insert before the loop than inside */
418  list tstats = gen_copy_seq(c->stats);
419  FOREACH(STATEMENT,st,tstats) {
420  if(recurse_statements_conflict_p(st,body) ) { // conflict with other iterations
422  gen_remove_once(&c->stats,st);
423  }
424  }
425  gen_free_list(tstats);
426 
427  /* then we propagate the dma inside the body */
428  context cb = context_dup(c);
429  delay_communications_statement(body,c,NULL);
430 
431 
432  /* then we check for conflicts with indices or over iterations */
433  tstats = gen_copy_seq(c->stats);
434  FOREACH(STATEMENT,st,tstats) {
435  if(statements_conflict_p(st,s) ||// conflict with the iteration
436  recurse_statements_conflict_p(st,body) ) { // conflict with other iterations
437  insert_statement_in_block(body,st,c->backward,NULL);
438  gen_remove_once(&c->stats,st);
439  }
440  }
441  gen_free_list(tstats);
442  /* if statements have been moved outside the loop
443  * then we (may) need to flatten
444  */
445  FOREACH(STATEMENT,st,c->stats) {
447  c->need_flatten|=true;
448  break;
449  }
450  }
451  gen_free_list(cb.stats);
452 
453 }
static void delay_communications_statement(statement, context *, list *block)
Definition: delay.c:455
static void manage_conflicts(statement s, context *c, bool before, list *block)
Definition: delay.c:304
static bool statements_conflict_p(statement s0, statement s1)
checks if there exist a conflict between s0 and s1 according to the dependency graph
Definition: delay.c:161
static bool recurse_statements_conflict_p(statement s, statement in)
checks if there is a conflict between s and any statement in in
Definition: delay.c:247
static context context_dup(context *c)
Definition: delay.c:262
static void insert_statement_in_block(statement s, statement inserted, bool before, list *block)
Definition: delay.c:292
#define gen_chunk_undefined_p(c)
Definition: genC.h:75
void gen_remove_once(list *pl, const void *o)
Remove the first occurence of o in list pl:
Definition: list.c:691
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
void * gen_find_eq(const void *item, const list seq)
Definition: list.c:422
loop statement_loop(statement)
Get the loop of a statement.
Definition: statement.c:1374
whileloop statement_whileloop(statement)
Get the whileloop of a statement.
Definition: statement.c:1383
forloop statement_forloop(statement)
Get the forloop of a statement.
Definition: statement.c:1426
bool statement_whileloop_p(statement)
Definition: statement.c:354
bool statement_forloop_p(statement)
Definition: statement.c:374
bool statement_loop_p(statement)
Definition: statement.c:349
#define loop_body(x)
Definition: ri.h:1644
#define whileloop_body(x)
Definition: ri.h:3162
#define statement_undefined_p(x)
Definition: ri.h:2420
#define forloop_body(x)
Definition: ri.h:1372

References context::backward, context_dup(), delay_communications_statement(), FOREACH, forloop_body, gen_chunk_undefined_p, gen_copy_seq(), gen_find_eq(), gen_free_list(), gen_remove_once(), insert_statement_in_block(), loop_body, manage_conflicts(), context::need_flatten, pips_assert, recurse_statements_conflict_p(), STATEMENT, statement_forloop(), statement_forloop_p(), statement_loop(), statement_loop_p(), statement_undefined, statement_undefined_p, statement_whileloop(), statement_whileloop_p(), statements_conflict_p(), context::stats, and whileloop_body.

Referenced by delay_communications_statement().

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

◆ delay_communications_call()

static void delay_communications_call ( statement  s,
context c,
list block 
)
static

memorize additional dma

Definition at line 316 of file delay.c.

316  {
318  /* memorize additional dma */
319  if( (c->backward && simd_load_stat_p(s)) ||
320  (!c->backward && simd_store_stat_p(s)) ) {
324  statement_ordering(s)=o;
329  }
330 }
statement copy_statement(statement p)
STATEMENT.
Definition: ri.c:2186
bool simd_load_stat_p(statement stat)
Definition: delay.c:111
bool simd_store_stat_p(statement stat)
Definition: delay.c:119
void free(void *)
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
bool empty_comments_p(const char *)
Definition: statement.c:107
#define empty_comments
Empty comments (i.e.
#define statement_ordering(x)
Definition: ri.h:2454
#define statement_declarations(x)
Definition: ri.h:2460
#define statement_comments(x)
Definition: ri.h:2456
#define intptr_t
Definition: stdint.in.h:294

References context::backward, CONS, copy_statement(), empty_comments, empty_comments_p(), free(), gen_free_list(), intptr_t, make_continue_instruction(), manage_conflicts(), NIL, simd_load_stat_p(), simd_store_stat_p(), STATEMENT, statement_comments, statement_declarations, statement_ordering, context::stats, and update_statement_instruction().

Referenced by delay_communications_statement().

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

◆ delay_communications_init()

static void delay_communications_init ( )
static

Definition at line 589 of file delay.c.

589  {
595 }
static bool __delay_communications_patch_properties
Definition: delay.c:588
static bool delay_communications_interprocedurally_p
Definition: delay.c:73
#define graph_undefined_p(x)
Definition: graph.h:61
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
#define callees_callees(x)
Definition: ri.h:675

References __delay_communications_patch_properties, callees_callees, db_get_memory_resource(), delay_communications_interprocedurally_p, dependence_graph, ENDP, get_current_module_entity(), graph_undefined_p, module_local_name(), and pips_assert.

Referenced by delay_load_communications(), and delay_store_communications().

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

◆ delay_communications_inter()

bool delay_communications_inter ( const char *  module_name)
Parameters
module_nameodule_name

Definition at line 970 of file delay.c.

970  {
973 }
static bool delay_communications(const char *module_name)
Definition: delay.c:924

References delay_communications(), delay_communications_interprocedurally_p, and module_name().

+ Here is the call graph for this function:

◆ delay_communications_interprocedurally()

static void delay_communications_interprocedurally ( context c)
static

Definition at line 561 of file delay.c.

561  {
563  if(ENDP(callers)) {
564  pips_user_warning("no caller for function `%s', falling back to intra-procedural delaying\n",get_current_module_name());
566  }
567  else {
568  list callers_statement = callers_to_statements(callers);
569 
570  for(list citer=callers,siter=callers_statement;!ENDP(citer);POP(citer),POP(siter)) {
571  c->caller=module_name_to_entity( STRING(CAR(citer)) );
572  c->caller_statement = STATEMENT(CAR(siter));
575  }
576 
577  for(list citer=callers,siter=callers_statement;!ENDP(citer);POP(citer),POP(siter)) {
578  string caller_name = STRING(CAR(citer));
579  statement caller_statement = STATEMENT(CAR(siter));
580  module_reorder(caller_statement);
581  DB_PUT_MEMORY_RESOURCE(DBR_CODE, caller_name,caller_statement);
582  DB_PUT_MEMORY_RESOURCE(DBR_CALLEES, caller_name,compute_callees(caller_statement));
583  }
584  }
585 }
static void delay_communications_intraprocedurally(statement module_stat, context *c)
transform each caller into a load / call /store sequence
Definition: delay.c:556
static void do_delay_communications_interprocedurally(call ca, context *c)
Definition: delay.c:542
static const char * caller_name
Definition: alias_check.c:122
list callers_to_statements(list callers)
given a list callers of module name calling module called module return a list of their body
Definition: callgraph.c:163
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
Definition: genC.h:285
#define STRING(x)
Definition: genC.h:87
const char * get_current_module_name(void)
Get the name of the current module.
Definition: static.c:121
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
bool gen_true2(__attribute__((unused)) gen_chunk *u1, __attribute__((unused)) void *u2)
Definition: genClib.c:2785
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define pips_user_warning
Definition: misc-local.h:146
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
statement caller_statement
Definition: delay.c:259

References call_domain, callees_callees, context::caller, caller_name, context::caller_statement, callers_to_statements(), CAR, clean_up_sequences(), compute_callees(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, delay_communications_intraprocedurally(), do_delay_communications_interprocedurally(), ENDP, gen_context_recurse, gen_true2(), get_current_module_entity(), get_current_module_name(), get_current_module_statement(), module_local_name(), module_name_to_entity(), module_reorder(), pips_user_warning, POP, STATEMENT, and STRING.

Referenced by delay_load_communications(), and delay_store_communications().

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

◆ delay_communications_intra()

bool delay_communications_intra ( const char *  module_name)
Parameters
module_nameodule_name

Definition at line 974 of file delay.c.

974  {
977 }

References delay_communications(), delay_communications_interprocedurally_p, and module_name().

+ Here is the call graph for this function:

◆ delay_communications_intraprocedurally()

static void delay_communications_intraprocedurally ( statement  module_stat,
context c 
)
static

transform each caller into a load / call /store sequence

Definition at line 556 of file delay.c.

556  {
557  FOREACH(STATEMENT,s,c->stats)
558  insert_statement(module_stat,s,c->backward);
559  gen_free_list(c->stats);c->stats=NIL;
560 }
void insert_statement(statement, statement, bool)
This is the normal entry point.
Definition: statement.c:2570

References context::backward, FOREACH, gen_free_list(), insert_statement(), NIL, STATEMENT, and context::stats.

Referenced by delay_communications_interprocedurally(), delay_load_communications(), and delay_store_communications().

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

◆ delay_communications_reset()

static void delay_communications_reset ( )
static

◆ delay_communications_sequence()

static void delay_communications_sequence ( sequence  s,
context c,
list block 
)
static

Definition at line 270 of file delay.c.

270  {
271  pips_assert("true", block==block);
273  if(c->backward) stats=gen_nreverse(stats); //reverse the walking when performing backward movements
274  FOREACH(STATEMENT,st,stats) {
276  }
277  gen_free_list(stats);
278 }
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304

References context::backward, delay_communications_statement(), FOREACH, gen_copy_seq(), gen_free_list(), gen_nreverse(), pips_assert, sequence_statements, and STATEMENT.

Referenced by delay_communications_statement().

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

◆ delay_communications_statement()

static void delay_communications_statement ( statement  s,
context c,
list block 
)
static

we could do better

Definition at line 455 of file delay.c.

455  {
457  switch(instruction_tag(i)) {
458  case is_instruction_expression:/* we could do better */
459  case is_instruction_call:
460  delay_communications_call(s,c,block);break;
463  case is_instruction_test:
464  delay_communications_test(s,c,NULL);break;
465  case is_instruction_loop:
468  delay_communications_anyloop(s,c,NULL);break;
469  default:
470  pips_user_warning("not implemented yet, full memory barrier is assumed\n");
471  {
472  list tstats= gen_copy_seq(c->stats);
473  FOREACH(STATEMENT,st,tstats) {
475  gen_remove_once(&c->stats,st);
476  }
477  gen_free_list(tstats);
478  }
479 
480  };
481  pips_assert("everything is ok",statement_consistent_p(s));
482 }
static void delay_communications_test(statement s, context *c, list *block)
Definition: delay.c:332
static void delay_communications_call(statement s, context *c, list *block)
Definition: delay.c:316
static void delay_communications_sequence(sequence s, context *c, list *block)
Definition: delay.c:270
static void delay_communications_anyloop(statement s, context *c, list *block)
Definition: delay.c:407
@ 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_sequence
Definition: ri.h:1469
@ is_instruction_forloop
Definition: ri.h:1477
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define instruction_sequence(x)
Definition: ri.h:1514

References context::backward, delay_communications_anyloop(), delay_communications_call(), delay_communications_sequence(), delay_communications_test(), FOREACH, gen_copy_seq(), gen_free_list(), gen_remove_once(), insert_statement_in_block(), instruction_sequence, instruction_tag, is_instruction_call, is_instruction_expression, is_instruction_forloop, is_instruction_loop, is_instruction_sequence, is_instruction_test, is_instruction_whileloop, pips_assert, pips_user_warning, STATEMENT, statement_consistent_p(), statement_instruction, and context::stats.

Referenced by delay_communications_anyloop(), delay_communications_sequence(), delay_communications_test(), delay_load_communications(), and delay_store_communications().

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

◆ delay_communications_test()

static void delay_communications_test ( statement  s,
context c,
list block 
)
static

explore both branches independently

manage state consistency after s : currently very pessimistic: if a dma is made on a branch, it must be done at the end of the branch. A more elaborated version could be to check that same pointers are stored and that they can be merged later ...

the same for the false branch

now we have the opposite case: a dma was made on a branch but not on the other one, in that case we must do it at the end of the other branch

true branch

false branch

insert it if it's missing somewhere

Definition at line 332 of file delay.c.

332  {
333  manage_conflicts(s,c,!c->backward, block);
334  /* explore both branches independently */
335  test t = statement_test(s);
336  context c0 = context_dup(c), c1=context_dup(c);
339  /* manage state consistency after s :
340  * currently very pessimistic: if a dma is made on a branch, it must be
341  * done at the end of the branch.
342  * A more elaborated version could be to check that same pointers are stored
343  * and that they can be merged later ...
344  */
345  list tstats = gen_copy_seq(c0.stats);
346  FOREACH(STATEMENT,st0,tstats) {
347  intptr_t o = statement_ordering(st0);
348  bool new = true;
349  FOREACH(STATEMENT,st,c->stats) {
350  if(statement_ordering(st) == o ) {
351  new=false;
352  break;
353  }
354  }
355  if(new) {
357  gen_remove_once(&c0.stats,st0);
358  gen_remove_once(&c->stats,st0);
359  }
360  }
361  gen_free_list(tstats);
362  /* the same for the false branch */
363  tstats = gen_copy_seq(c1.stats);
364  FOREACH(STATEMENT,st1,tstats) {
365  intptr_t o = statement_ordering(st1);
366  bool new = true;
367  FOREACH(STATEMENT,st,c->stats) {
368  if(statement_ordering(st) == o ) {
369  new=false;
370  break;
371  }
372  }
373  if(new) {
375  gen_remove_once(&c1.stats,st1);
376  gen_remove_once(&c->stats,st1);
377  }
378  }
379  gen_free_list(tstats);
380  /* now we have the opposite case: a dma was made on a branch
381  * but not on the other one,
382  * in that case we must do it at the end of the other branch
383  */
384  tstats = gen_copy_seq(c->stats);
385  FOREACH(STATEMENT,st,tstats) {
387  /* true branch */
388  bool tfound =false,ffound=false;
389  FOREACH(STATEMENT,st0,c0.stats)
390  if((tfound= (o == statement_ordering(st0)))) break;
391  /* false branch */
392  FOREACH(STATEMENT,st1,c1.stats)
393  if((ffound= (o == statement_ordering(st1)))) break;
394  /* insert it if it's missing somewhere */
395  if(tfound && !ffound ) {
397  gen_remove_once(&c->stats,st);
398  }
399  if(!tfound && ffound ) {
401  gen_remove_once(&c->stats,st);
402  }
403  }
404  gen_free_list(tstats);
405 }
if(!(yy_init))
Definition: genread_lex.c:1029
test statement_test(statement)
Get the test of a statement.
Definition: statement.c:1348
#define test_false(x)
Definition: ri.h:2837
#define test_true(x)
Definition: ri.h:2835

References context::backward, context_dup(), copy_statement(), delay_communications_statement(), FOREACH, gen_copy_seq(), gen_free_list(), gen_remove_once(), insert_statement_in_block(), intptr_t, manage_conflicts(), STATEMENT, statement_ordering, statement_test(), context::stats, test_false, and test_true.

Referenced by delay_communications_statement().

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

◆ delay_load_communications()

bool delay_load_communications ( char *  module_name)

This phase looks for load or save statements that can be put out of the loop body and move these statements, if possible.

Get the code of the module.

Go through all the statements

then a backward translation

propagate inter procedurally , except if we have no caller

clean badly generated sequences

Parameters
module_nameodule_name

Definition at line 607 of file delay.c.

608 {
609  /* Get the code of the module. */
611  statement module_stat = (statement)db_get_memory_resource(DBR_CODE, module_name, true);
612  set_ordering_to_statement(module_stat);
614  set_current_module_statement( module_stat);
616  (statement_effects)db_get_memory_resource(DBR_PROPER_EFFECTS, module_name, true)
617  );
620  (statement_effects)db_get_memory_resource(DBR_CUMULATED_EFFECTS, module_name, true)
621  );
622 
623 
624  debug_on("DELAY_COMMUNICATIONS_DEBUG_LEVEL");
627 
628  /* Go through all the statements */
629  context c = { true, NIL, true, false , NULL, NULL };
630 
631  /* then a backward translation */
632  delay_communications_statement(module_stat,&c,NULL);
633 
634  /* propagate inter procedurally , except if we have no caller*/
637  else
639 
640  if(c.need_flatten)
642 
643  /* clean badly generated sequences */
644  clean_up_sequences(module_stat);
645 
647 
648 
649  pips_assert("Statement is consistent\n" , statement_consistent_p(module_stat));
650 
651  module_reorder(module_stat);
652  DB_PUT_MEMORY_RESOURCE(DBR_CODE, module_name, module_stat);
653  DB_PUT_MEMORY_RESOURCE(DBR_CALLEES, module_name, compute_callees(module_stat));
654 
655  debug_off();
656 
662 
663  return c.result;
664 }
static void delay_communications_reset()
Definition: delay.c:596
static void delay_communications_interprocedurally(context *c)
Definition: delay.c:561
static void delay_communications_init()
Definition: delay.c:589
#define false
Definition: newgen_types.h:80

References clean_up_sequences(), compute_callees(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, delay_communications_init(), delay_communications_interprocedurally(), delay_communications_interprocedurally_p, delay_communications_intraprocedurally(), delay_communications_reset(), delay_communications_statement(), dependence_graph, false, get_proper_rw_effects(), module, module_name(), module_name_to_entity(), module_reorder(), context::need_flatten, NIL, pips_assert, remove_preferences(), reset_cumulated_rw_effects(), reset_current_module_entity(), reset_current_module_statement(), reset_ordering_to_statement(), reset_proper_rw_effects(), context::result, set_cumulated_rw_effects(), set_current_module_entity(), set_current_module_statement(), set_ordering_to_statement(), set_proper_rw_effects(), statement_consistent_p(), and statement_flatten_declarations().

Referenced by delay_load_communications_inter(), and delay_load_communications_intra().

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

◆ delay_load_communications_inter()

bool delay_load_communications_inter ( char *  module_name)
Parameters
module_nameodule_name

Definition at line 665 of file delay.c.

665  {
668 }
bool delay_load_communications(char *module_name)
This phase looks for load or save statements that can be put out of the loop body and move these stat...
Definition: delay.c:607

References delay_communications_interprocedurally_p, delay_load_communications(), and module_name().

+ Here is the call graph for this function:

◆ delay_load_communications_intra()

bool delay_load_communications_intra ( char *  module_name)
Parameters
module_nameodule_name

Definition at line 669 of file delay.c.

References delay_communications_interprocedurally_p, delay_load_communications(), and module_name().

+ Here is the call graph for this function:

◆ delay_store_communications()

bool delay_store_communications ( char *  module_name)

Get the code of the module.

Go through all the statements

a first forward translation

propagate inter procedurally , except if we have no caller

clean badly generated sequences

Parameters
module_nameodule_name

Definition at line 674 of file delay.c.

675 {
676  /* Get the code of the module. */
678  statement module_stat = (statement)db_get_memory_resource(DBR_CODE, module_name, true);
679  set_ordering_to_statement(module_stat);
681  set_current_module_statement( module_stat);
683  (statement_effects)db_get_memory_resource(DBR_PROPER_EFFECTS, module_name, true)
684  );
687  (statement_effects)db_get_memory_resource(DBR_CUMULATED_EFFECTS, module_name, true)
688  );
690 
692 
693  debug_on("DELAY_COMMUNICATIONS_DEBUG_LEVEL");
694 
695 
696 
697  /* Go through all the statements */
698  context c = { true, NIL, false, false, NULL, NULL };
699 
700  /* a first forward translation */
701  delay_communications_statement(module_stat,&c,NULL);
702 
703  /* propagate inter procedurally , except if we have no caller*/
706  else
708 
709  if(c.need_flatten)
711 
712  /* clean badly generated sequences */
713  clean_up_sequences(module_stat);
714 
716 
717  pips_assert("Statement is consistent\n" , statement_consistent_p(module_stat));
718 
719  module_reorder(module_stat);
720  DB_PUT_MEMORY_RESOURCE(DBR_CODE, module_name, module_stat);
721  DB_PUT_MEMORY_RESOURCE(DBR_CALLEES, module_name, compute_callees(module_stat));
722 
723  debug_off();
724 
730 
731  return c.result;
732 }

References clean_up_sequences(), compute_callees(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, delay_communications_init(), delay_communications_interprocedurally(), delay_communications_interprocedurally_p, delay_communications_intraprocedurally(), delay_communications_reset(), delay_communications_statement(), dependence_graph, get_proper_rw_effects(), module, module_name(), module_name_to_entity(), module_reorder(), context::need_flatten, NIL, pips_assert, remove_preferences(), reset_cumulated_rw_effects(), reset_current_module_entity(), reset_current_module_statement(), reset_ordering_to_statement(), reset_proper_rw_effects(), context::result, set_cumulated_rw_effects(), set_current_module_entity(), set_current_module_statement(), set_ordering_to_statement(), set_proper_rw_effects(), statement_consistent_p(), and statement_flatten_declarations().

Referenced by delay_store_communications_inter(), and delay_store_communications_intra().

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

◆ delay_store_communications_inter()

bool delay_store_communications_inter ( char *  module_name)
Parameters
module_nameodule_name

Definition at line 733 of file delay.c.

733  {
736 }
bool delay_store_communications(char *module_name)
Definition: delay.c:674

References delay_communications_interprocedurally_p, delay_store_communications(), and module_name().

+ Here is the call graph for this function:

◆ delay_store_communications_intra()

bool delay_store_communications_intra ( char *  module_name)
Parameters
module_nameodule_name

Definition at line 737 of file delay.c.

References delay_communications_interprocedurally_p, delay_store_communications(), and module_name().

+ Here is the call graph for this function:

◆ dma_conflict_p()

static bool dma_conflict_p ( conflict  c)
static

be conservative

Definition at line 142 of file delay.c.

143 {
144  effect source = conflict_source(c),
145  sink = conflict_sink(c);
146  descriptor dsource = effect_descriptor(source),
147  dsink = effect_descriptor(sink);
148  if(descriptor_convex_p(dsource) && descriptor_convex_p(dsink))
149  {
150  Psysteme psource = descriptor_convex(dsource),
151  psink = descriptor_convex(dsink);
152  return !(sc_inclusion_p(psink,psource) || sc_inclusion_p(psource,psink));
153  }
154  /* be conservative */
155  return true;
156 }
#define conflict_sink(x)
Definition: dg.h:167
#define conflict_source(x)
Definition: dg.h:165
#define descriptor_convex_p(x)
Definition: effects.h:599
#define effect_descriptor(x)
Definition: effects.h:646
#define descriptor_convex(x)
Definition: effects.h:601
#define sc_inclusion_p(ps1, ps2)
Definition: union-local.h:80

References conflict_sink, conflict_source, descriptor_convex, descriptor_convex_p, effect_descriptor, and sc_inclusion_p.

Referenced by dma_statements_conflict_p().

+ Here is the caller graph for this function:

◆ dma_statements_conflict_p()

static bool dma_statements_conflict_p ( statement  s0,
statement  s1 
)
static

Definition at line 216 of file delay.c.

216  {
224  if(dma_conflict_p(c)) return true;
225  }
226  }
227  }
228  }
229  return false;
230 }
static bool dma_conflict_p(conflict c)
Definition: delay.c:142
#define CONFLICT(x)
CONFLICT.
Definition: dg.h:134
#define dg_arc_label_conflicts(x)
Definition: dg.h:201
#define successor_vertex(x)
Definition: graph.h:118
#define successor_arc_label(x)
Definition: graph.h:116
#define vertex_successors(x)
Definition: graph.h:154
#define SUCCESSOR(x)
SUCCESSOR.
Definition: graph.h:86
#define graph_vertices(x)
Definition: graph.h:82
#define VERTEX(x)
VERTEX.
Definition: graph.h:122
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 CONFLICT, dependence_graph, dg_arc_label_conflicts, dma_conflict_p(), FOREACH, graph_vertices, intptr_t, s1, statement_ordering, SUCCESSOR, successor_arc_label, successor_vertex, VERTEX, vertex_successors, and vertex_to_statement().

Referenced by do_recurse_statements_conflict_p().

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

◆ dmas_invert_p()

static bool dmas_invert_p ( statement  s0,
statement  s1 
)
static

this occurs when structures are involved

dma annihilates

Definition at line 742 of file delay.c.

742  {
743  pips_assert("called on dmas",simd_dma_stat_p(s0) && simd_dma_stat_p(s1));
746  list pr=NIL,pw=NIL,sr=NIL,sw=NIL;
747  FOREACH(REGION,r,p_reg) {
749  if(region_write_p(r)) {
750  pw=CONS(REGION,r,pw);
751  }
752  else {
753  pr=CONS(REGION,r,pr);
754  }
755  }
756  }
757  FOREACH(REGION,r,s_reg) {
759  if(region_write_p(r)) {
760  sw=CONS(REGION,r,sw);
761  }
762  else {
763  sr=CONS(REGION,r,sr);
764  }
765  }
766  }
767  /* this occurs when structures are involved */
768  if( ENDP(sw) ||
769  ENDP(sr) ||
770  ENDP(pw) ||
771  ENDP(pr)) {
772  pips_user_warning("regions for dma not properly computed\n");
773  return false;
774  }
775  else {
776  /* dma annihilates */
777  bool annihilate = gen_length(pw) == gen_length(sr) &&
778  gen_length(pr) == gen_length(sw) ;
779  if( annihilate) {
780  for(list i=pw,j=sr;!ENDP(i)&&!ENDP(j);POP(i),POP(j)) {
781  region ri = REGION(CAR(i)),
782  rj = REGION(CAR(j));
783  if(!( annihilate = (reference_equal_p(region_any_reference(ri),region_any_reference(rj)) &&
785  ) ) break;
786 
787  }
788  if(annihilate) {
789  for(list i=sw,j=pr;!ENDP(i)&&!ENDP(j);POP(i),POP(j)) {
790  region ri = REGION(CAR(i)),
791  rj = REGION(CAR(j));
792  if(!( annihilate = (reference_equal_p(region_any_reference(ri),region_any_reference(rj)) &&
794  ) ) break;
795 
796  }
797  }
798  }
799  return annihilate;
800  }
801 }
bool simd_dma_stat_p(statement stat)
This function returns true if the statement is a simd loadsave statement.
Definition: delay.c:127
#define region_any_reference(reg)
To be avoided.
#define region_write_p(reg)
#define region_system(reg)
#define REGION
#define region
simulation of the type region
list load_cumulated_rw_effects_list(statement)
size_t gen_length(const list l)
Definition: list.c:150
bool reference_equal_p(reference r1, reference r2)
Definition: expression.c:1500
bool array_reference_p(reference r)
predicates on references
Definition: expression.c:1861
#define sc_equal_p(ps1, ps2)
Definition: union-local.h:83

References array_reference_p(), CAR, CONS, ENDP, FOREACH, gen_length(), load_cumulated_rw_effects_list(), NIL, pips_assert, pips_user_warning, POP, reference_equal_p(), region, REGION, region_any_reference, region_system, region_write_p, s1, sc_equal_p, and simd_dma_stat_p().

Referenced by do_remove_redundant_communications_in_anyloop(), and do_remove_redundant_communications_in_sequence().

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

◆ do_delay_communications_interprocedurally()

static void do_delay_communications_interprocedurally ( call  ca,
context c 
)
static

there should be checks there !

Definition at line 542 of file delay.c.

542  {
545  FOREACH(STATEMENT,s,c->stats) {
547  statement new = translate_arguments(ca,s);
548  /* there should be checks there ! */
549  insert_statement(parent,new,c->backward);
550  }
551  }
552 }
static void promote_local_entities(statement s, entity caller, statement caller_statement)
if some local variables are going to be accessed inter procedurally, promote them to global variables
Definition: delay.c:502
static statement translate_arguments(call ca, statement s)
Definition: delay.c:484
gen_chunk * gen_get_ancestor(int, const void *)
return the first ancestor object found of the given type.
Definition: genClib.c:3560
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
#define call_function(x)
Definition: ri.h:709
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362

References context::backward, call_function, context::caller, context::caller_statement, FOREACH, gen_get_ancestor(), get_current_module_entity(), insert_statement(), promote_local_entities(), same_entity_p(), STATEMENT, statement_domain, context::stats, and translate_arguments().

Referenced by delay_communications_interprocedurally().

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

◆ do_recurse_statements_conflict_p()

static void do_recurse_statements_conflict_p ( statement  s,
conflict_t c 
)
static

helper for recurse_statements_conflict_p

Definition at line 239 of file delay.c.

239  {
243  gen_recurse_stop(0);
244 }
static bool statements_conflict_relaxed_p(statement s0, statement s1, bool load_p)
same as statements_conflict_p but W-* conflicts are ignored if load_p, R-* conflicts are ignored if n...
Definition: delay.c:192
static bool dma_statements_conflict_p(statement s0, statement s1)
Definition: delay.c:216
void gen_recurse_stop(void *obj)
Tells the recursion not to go in this object.
Definition: genClib.c:3251
statement s
Definition: delay.c:234
bool conflict
Definition: delay.c:235

References conflict_t::conflict, dma_statements_conflict_p(), gen_recurse_stop(), conflict_t::s, simd_load_stat_p(), statement_ordering, and statements_conflict_relaxed_p().

Referenced by recurse_statements_conflict_p().

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

◆ do_remove_preference()

static bool do_remove_preference ( cell  c)
static

helper to transform preferences in references

Definition at line 76 of file delay.c.

76  {
77  if(cell_preference_p(c)) {
80  );
83  cell_reference(c)=r;
84  }
85  return true;
86 }
void free_preference(preference p)
Definition: ri.c:1829
reference copy_reference(reference p)
REFERENCE.
Definition: ri.c:2047
#define cell_reference(x)
Definition: effects.h:469
#define cell_preference(x)
Definition: effects.h:472
@ is_cell_reference
Definition: effects.h:445
#define cell_tag(x)
Definition: effects.h:466
#define cell_preference_p(x)
Definition: effects.h:470
#define preference_reference(x)
Definition: ri.h:2102

References cell_preference, cell_preference_p, cell_reference, cell_tag, copy_reference(), free_preference(), is_cell_reference, and preference_reference.

Referenced by remove_preferences().

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

◆ do_remove_redundant_communications_in_anyloop()

static bool do_remove_redundant_communications_in_anyloop ( statement  parent,
statement  body 
)
static

skip declarations

look for heading dma statements

look for trailing dma statements

insert them around the loop

flatten_code if needed

and remove them from the alternate list

Definition at line 851 of file delay.c.

851  {
852  bool need_flatten=false;
853  if(statement_block_p(body)) {
854  list b = statement_block(body);
855  list iordered=b;
856  /* skip declarations */
857  while(!ENDP(iordered) &&
858  declaration_statement_p(STATEMENT(CAR(iordered))) ) POP(iordered);
859  bool skipped_declarations= (iordered != b);
860  list reversed = gen_nreverse(gen_copy_seq(iordered));
861  /* look for heading dma statements */
862  iordered=gen_copy_seq(iordered); // to be consistent with `reversed' allocation
863  select_independent_dmas(&iordered, parent);
864  /* look for trailing dma statements */
865  select_independent_dmas(&reversed, parent);
866 
867  bool did_something=false;
868  for(list oter=iordered;!ENDP(oter);POP(oter)) {
869  statement os = STATEMENT(CAR(oter));
870  FOREACH(STATEMENT,rs,reversed) {
871  if(simd_dma_stat_p(os) &&
872  simd_dma_stat_p(rs) &&
873  dmas_invert_p(os,rs)) {
874  gen_remove_once(&b,rs);
875  gen_remove_once(&b,os);
876  /* insert them around the loop */
877  insert_statement(parent,os,true);
878  insert_statement(parent,rs,false);
879  /* flatten_code if needed */
880  set re = get_referenced_entities(os);
881  set de = set_make(set_pointer);
883  if(set_intersection_p(de,re)) need_flatten = true;
884  set_free(de);set_free(re);
885  /* and remove them from the alternate list */
886  gen_remove_once(&b,rs);
887  gen_remove_once(&reversed,os);
888  did_something=true;
889  break;
890  }
891  }
892  }
893  gen_free_list(iordered);
894  gen_free_list(reversed);
895  if(did_something && skipped_declarations)
896  need_flatten=true;
898  }
899  return need_flatten;
900 }
static bool dmas_invert_p(statement s0, statement s1)
Definition: delay.c:742
static void select_independent_dmas(list *stats, statement parent)
Definition: delay.c:832
list statement_block(statement)
Get the list of block statements of a statement sequence.
Definition: statement.c:1338
set set_assign_list(set, const list)
assigns a list contents to a set all duplicated elements are lost
Definition: set.c:474
bool set_intersection_p(const set, const set)
returns whether s1 n s2 <> 0 complexity of the intersection
Definition: set.c:288
void set_free(set)
Definition: set.c:332
@ 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 get_referenced_entities(void *elem)
retrieves the set of entities used in elem beware that this entities may be formal parameters,...
Definition: entity.c:3063
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59

References CAR, declaration_statement_p(), dmas_invert_p(), ENDP, FOREACH, gen_copy_seq(), gen_free_list(), gen_nreverse(), gen_remove_once(), get_referenced_entities(), insert_statement(), POP, select_independent_dmas(), sequence_statements, set_assign_list(), set_free(), set_intersection_p(), set_make(), set_pointer, simd_dma_stat_p(), STATEMENT, statement_block(), statement_block_p, statement_declarations, and statement_sequence().

Referenced by do_remove_redundant_communications_in_forloop(), do_remove_redundant_communications_in_loop(), and do_remove_redundant_communications_in_whileloop().

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

◆ do_remove_redundant_communications_in_forloop()

static void do_remove_redundant_communications_in_forloop ( forloop  l,
bool need_flatten 
)
static

Definition at line 910 of file delay.c.

910  {
912 }
static bool do_remove_redundant_communications_in_anyloop(statement parent, statement body)
Definition: delay.c:851

References do_remove_redundant_communications_in_anyloop(), forloop_body, gen_get_ancestor(), and statement_domain.

Referenced by remove_redundant_communications().

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

◆ do_remove_redundant_communications_in_loop()

static void do_remove_redundant_communications_in_loop ( loop  l,
bool need_flatten 
)
static

Definition at line 902 of file delay.c.

References do_remove_redundant_communications_in_anyloop(), gen_get_ancestor(), loop_body, and statement_domain.

Referenced by remove_redundant_communications().

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

◆ do_remove_redundant_communications_in_sequence()

static void do_remove_redundant_communications_in_sequence ( sequence  s,
bool need_flatten 
)
static

remove the second statements from the original sequence if we have load ; store , the store is useless and the load will be removed by a used_def_elim phase if we have store ; load, it 's the same

Definition at line 803 of file delay.c.

803  {
804  pips_assert("true",need_flatten==need_flatten );
807  FOREACH(STATEMENT,st,ts) {
808  if(simd_dma_stat_p(st)) {
809  if(!statement_undefined_p(prev)) { // do they annihilate each other ?
810  if(dmas_invert_p(st,prev)) {
811  /* remove the second statements from the original sequence
812  * if we have load ; store , the store is useless
813  * and the load will be removed by a used_def_elim phase
814  * if we have store ; load, it 's the same
815  */
816  // gen_remove_once(&sequence_statements(s),prev);
818  }
819  else
820  prev=st;
821  prev=statement_undefined;
822  }
823  else
824  prev=st;
825  }
826  else
827  prev=statement_undefined;
828  }
829  gen_free_list(ts);
830 }

References dmas_invert_p(), FOREACH, gen_copy_seq(), gen_free_list(), gen_remove_once(), pips_assert, sequence_statements, simd_dma_stat_p(), STATEMENT, statement_undefined, and statement_undefined_p.

Referenced by remove_redundant_communications().

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

◆ do_remove_redundant_communications_in_whileloop()

static void do_remove_redundant_communications_in_whileloop ( whileloop  l,
bool need_flatten 
)
static

Definition at line 906 of file delay.c.

References do_remove_redundant_communications_in_anyloop(), gen_get_ancestor(), statement_domain, and whileloop_body.

Referenced by remove_redundant_communications().

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

◆ insert_statement_in_block()

static void insert_statement_in_block ( statement  s,
statement  inserted,
bool  before,
list block 
)
static

Definition at line 292 of file delay.c.

292  {
293  if(statement_block_p(s))
294  insert_statement(s,inserted,before);
295  else {
297  if(before)
298  *block=gen_insert_before(inserted,s,*block);
299  else
300  gen_insert_after(inserted,s,*block);
301  }
302 }
static void create_block_if_needed(statement *s, list **block)
Definition: delay.c:279
void gen_insert_after(const void *no, const void *o, list l)
Definition: list.c:223
list gen_insert_before(const void *no, const void *o, list l)
Definition: list.c:238

References create_block_if_needed(), gen_insert_after(), gen_insert_before(), insert_statement(), and statement_block_p.

Referenced by delay_communications_anyloop(), delay_communications_statement(), delay_communications_test(), and manage_conflicts().

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

◆ manage_conflicts()

static void manage_conflicts ( statement  s,
context c,
bool  before,
list block 
)
static

check conflicts with current stats

Definition at line 304 of file delay.c.

304  {
305  /* check conflicts with current stats */
306  list tstats = gen_copy_seq(c->stats);
307  FOREACH(STATEMENT,st,tstats) {
308  if(statements_conflict_p(s,st)) {
309  insert_statement_in_block(s,st,before,block);
310  gen_remove_once(&c->stats,st);
311  }
312  }
313  gen_free_list(tstats);
314 }

References FOREACH, gen_copy_seq(), gen_free_list(), gen_remove_once(), insert_statement_in_block(), STATEMENT, statements_conflict_p(), and context::stats.

Referenced by delay_communications_anyloop(), delay_communications_call(), and delay_communications_test().

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

◆ promote_local_entities()

static void promote_local_entities ( statement  s,
entity  caller,
statement  caller_statement 
)
static

if some local variables are going to be accessed inter procedurally, promote them to global variables

Definition at line 502 of file delay.c.

502  {
503  pips_assert("true", caller==caller && caller_statement==caller_statement);
505  list le = NIL;
506  SET_FOREACH(entity,e,re) {
508  !formal_parameter_p(e) ) {
509  le=CONS(ENTITY,e,le);
510  }
511  }
512  set_free(re);
513  gen_sort_list(le,(gen_cmp_func_t)compare_entities);//ensure determinism
514  FOREACH(ENTITY,e,le) {
515  entity new = entity_undefined;
516  if(entity_scalar_p(e)) {
518  entity_user_name(e),
521  );
522 
523  }
524  else {
525  pips_assert("not scalars -> array\n",entity_array_p(e));
527  entity_user_name(e),
531  );
532  }
539  }
540 }
basic copy_basic(basic p)
BASIC.
Definition: ri.c:104
void statement_split_initializations(statement s)
Recurse through the statements of s and split local declarations.
Definition: flatten_code.c:733
void replace_entity(void *s, entity old, entity new)
per variable version of replace_entities.
Definition: replace.c:113
list gen_full_copy_list(list l)
Copy a list structure with element copy.
Definition: list.c:535
void gen_sort_list(list l, gen_cmp_func_t compare)
Sorts a list of gen_chunks in place, to avoid allocations...
Definition: list.c:796
#define SET_FOREACH(type_name, the_item, the_set)
enumerate set elements in their internal order.
Definition: newgen_set.h:78
int(* gen_cmp_func_t)(const void *, const void *)
Definition: newgen_types.h:114
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
int compare_entities(const entity *pe1, const entity *pe2)
Comparison function for qsort.
Definition: entity.c:1328
bool entity_array_p(entity e)
Is e a variable with an array type?
Definition: entity.c:754
bool local_entity_of_module_p(entity e, entity module)
This test shows that "e" has been declared in "module".
Definition: entity.c:1069
basic entity_basic(entity e)
return the basic associated to entity e if it's a function/variable/constant basic_undefined otherwis...
Definition: entity.c:1380
bool entity_scalar_p(entity)
The concrete type of e is a scalar type.
Definition: variable.c:1113
entity make_new_array_variable_with_prefix(const char *, entity, basic, list)
J'ai ameliore la fonction make_new_scalar_variable_with_prefix
Definition: variable.c:785
void RemoveLocalEntityFromDeclarations(entity, entity, statement)
Definition: variable.c:120
bool formal_parameter_p(entity)
Definition: variable.c:1489
entity make_new_scalar_variable_with_prefix(const char *, entity, basic)
Create a new scalar variable of type b in the given module.
Definition: variable.c:592
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define value_unknown_p(x)
Definition: ri.h:3077
#define type_variable(x)
Definition: ri.h:2949
#define entity_undefined
Definition: ri.h:2761
#define variable_dimensions(x)
Definition: ri.h:3122
#define entity_type(x)
Definition: ri.h:2792
#define entity_initial(x)
Definition: ri.h:2796
void AddEntityToModuleCompilationUnit(entity e, entity module)
Definition: module.c:301
entity module_entity_to_compilation_unit_entity(entity m)
Retrieve the compilation unit containing a module definition.
Definition: module.c:116

References AddEntityToModuleCompilationUnit(), compare_entities(), CONS, copy_basic(), ENTITY, entity_array_p(), entity_basic(), entity_initial, entity_scalar_p(), entity_type, entity_undefined, entity_user_name(), FOREACH, formal_parameter_p(), gen_full_copy_list(), gen_sort_list(), get_current_module_entity(), get_current_module_statement(), get_referenced_entities(), local_entity_of_module_p(), make_new_array_variable_with_prefix(), make_new_scalar_variable_with_prefix(), module_entity_to_compilation_unit_entity(), NIL, pips_assert, RemoveLocalEntityFromDeclarations(), replace_entity(), SET_FOREACH, set_free(), statement_split_initializations(), type_variable, value_unknown_p, and variable_dimensions.

Referenced by do_delay_communications_interprocedurally().

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

◆ recurse_statements_conflict_p()

static bool recurse_statements_conflict_p ( statement  s,
statement  in 
)
static

checks if there is a conflict between s and any statement in in

Definition at line 247 of file delay.c.

247  {
248  conflict_t c = { s, false };
250  return c.conflict;
251 }
static void do_recurse_statements_conflict_p(statement s, conflict_t *c)
helper for recurse_statements_conflict_p
Definition: delay.c:239
helper for do_recurse_statements_conflict_p
Definition: delay.c:233

References conflict_t::conflict, do_recurse_statements_conflict_p(), gen_context_recurse, gen_true2(), and statement_domain.

Referenced by delay_communications_anyloop().

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

◆ remove_preferences()

void remove_preferences ( void *  obj)

entry point to transform preferences in references

delay.c

Parameters
objbj

Definition at line 89 of file delay.c.

89  {
91 }
static bool do_remove_preference(cell c)
helper to transform preferences in references
Definition: delay.c:76
#define cell_domain
newgen_cell_interpretation_domain_defined
Definition: effects.h:85
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752

References cell_domain, do_remove_preference(), gen_null(), and gen_recurse.

Referenced by delay_communications(), delay_load_communications(), delay_store_communications(), loop_annotate(), and simdizer().

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

◆ remove_redundant_communications()

static bool remove_redundant_communications ( statement  s)
static

Definition at line 914 of file delay.c.

914  {
915  bool need_flatten=false;
916  gen_context_multi_recurse(s,&need_flatten,
921  NULL);
922  return need_flatten;
923 }
static void do_remove_redundant_communications_in_whileloop(whileloop l, bool *need_flatten)
Definition: delay.c:906
static void do_remove_redundant_communications_in_loop(loop l, bool *need_flatten)
Definition: delay.c:902
static void do_remove_redundant_communications_in_forloop(forloop l, bool *need_flatten)
Definition: delay.c:910
static void do_remove_redundant_communications_in_sequence(sequence s, bool *need_flatten)
Definition: delay.c:803
void gen_context_multi_recurse(void *o, void *context,...)
Multi-recursion with context function visitor.
Definition: genClib.c:3373
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
#define forloop_domain
newgen_extensions_domain_defined
Definition: ri.h:178
#define loop_domain
newgen_language_domain_defined
Definition: ri.h:218
#define whileloop_domain
newgen_variable_domain_defined
Definition: ri.h:466
#define sequence_domain
newgen_reference_domain_defined
Definition: ri.h:346

References do_remove_redundant_communications_in_forloop(), do_remove_redundant_communications_in_loop(), do_remove_redundant_communications_in_sequence(), do_remove_redundant_communications_in_whileloop(), forloop_domain, gen_context_multi_recurse(), gen_true(), loop_domain, sequence_domain, and whileloop_domain.

Referenced by delay_communications().

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

◆ select_independent_dmas()

static void select_independent_dmas ( list stats,
statement  parent 
)
static

Definition at line 832 of file delay.c.

832  {
833  list rtmp = NIL;
834  FOREACH(STATEMENT,st,*stats)
835  if(simd_dma_stat_p(st)) {
836  bool conflict = false;
837  FOREACH(STATEMENT,st2,rtmp) {
838  if((conflict=statements_conflict_p(st,st2)))
839  break;
840  }
841  conflict|=statements_conflict_p(st,parent);
842  if(conflict) break;
843  rtmp=CONS(STATEMENT,st,rtmp);
844  }
845  else
846  break;
847  gen_free_list(*stats);
848  *stats=rtmp;
849 }

References CONS, FOREACH, gen_free_list(), NIL, simd_dma_stat_p(), STATEMENT, and statements_conflict_p().

Referenced by do_remove_redundant_communications_in_anyloop().

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

◆ simd_dma_stat_p()

bool simd_dma_stat_p ( statement  stat)

This function returns true if the statement is a simd loadsave statement.

Parameters
stattat

Definition at line 127 of file delay.c.

128 {
129  return simd_load_stat_p(stat) || simd_store_stat_p(stat);
130 }

References simd_load_stat_p(), and simd_store_stat_p().

Referenced by dmas_invert_p(), do_remove_redundant_communications_in_anyloop(), do_remove_redundant_communications_in_sequence(), select_independent_dmas(), simd_stat_p(), and simd_trace_call().

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

◆ simd_load_call_p()

static bool simd_load_call_p ( call  c)
static

Definition at line 95 of file delay.c.

95  {
96  const char* funcName = entity_local_name(call_function(c));
97  const char* simd= get_string_property("ACCEL_LOAD");
98  return same_stringn_p(funcName, simd, strlen(simd));
99 }
char * get_string_property(const char *)
#define same_stringn_p(a, b, c)
Definition: misc-local.h:199
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 call_function, entity_local_name(), get_string_property(), and same_stringn_p.

Referenced by simd_load_stat_p().

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

◆ simd_load_stat_p()

bool simd_load_stat_p ( statement  stat)
Parameters
stattat

Definition at line 111 of file delay.c.

112 {
113  return statement_call_p(stat) && simd_load_call_p(statement_call(stat));
114 }
static bool simd_load_call_p(call c)
Definition: delay.c:95
call statement_call(statement)
Get the call of a statement.
Definition: statement.c:1406
bool statement_call_p(statement)
Definition: statement.c:364

References simd_load_call_p(), statement_call(), and statement_call_p().

Referenced by delay_communications_call(), do_recurse_statements_conflict_p(), and simd_dma_stat_p().

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

◆ simd_stat_p()

bool simd_stat_p ( statement  stat)

This function returns true if the statement is a simd statement.

Parameters
stattat

Definition at line 135 of file delay.c.

136 {
137  return simd_dma_stat_p(stat) || simd_work_stat_p(stat);
138 }
bool simd_work_stat_p(statement stat)
Definition: delay.c:115

References simd_dma_stat_p(), and simd_work_stat_p().

+ Here is the call graph for this function:

◆ simd_store_call_p()

static bool simd_store_call_p ( call  c)
static

Definition at line 105 of file delay.c.

105  {
106  const char* funcName = entity_local_name(call_function(c));
107  const char* simd= get_string_property("ACCEL_STORE");
108  return same_stringn_p(funcName, simd, strlen(simd));
109 }

References call_function, entity_local_name(), get_string_property(), and same_stringn_p.

Referenced by simd_store_stat_p().

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

◆ simd_store_stat_p()

bool simd_store_stat_p ( statement  stat)
Parameters
stattat

Definition at line 119 of file delay.c.

120 {
121  return statement_call_p(stat) && simd_store_call_p(statement_call(stat));
122 }
static bool simd_store_call_p(call c)
Definition: delay.c:105

References simd_store_call_p(), statement_call(), and statement_call_p().

Referenced by delay_communications_call(), simd_dma_stat_p(), statements_conflict_p(), and statements_conflict_relaxed_p().

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

◆ simd_work_call_p()

static bool simd_work_call_p ( call  c)
static

Definition at line 100 of file delay.c.

100  {
101  const char* funcName = entity_local_name(call_function(c));
102  const char* simd= get_string_property("ACCEL_WORK");
103  return same_stringn_p(funcName, simd, strlen(simd));
104 }

References call_function, entity_local_name(), get_string_property(), and same_stringn_p.

Referenced by simd_work_stat_p().

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

◆ simd_work_stat_p()

bool simd_work_stat_p ( statement  stat)
Parameters
stattat

Definition at line 115 of file delay.c.

116 {
117  return statement_call_p(stat) && simd_work_call_p(statement_call(stat));
118 }
static bool simd_work_call_p(call c)
Definition: delay.c:100

References simd_work_call_p(), statement_call(), and statement_call_p().

Referenced by simd_stat_p().

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

◆ statements_conflict_p()

static bool statements_conflict_p ( statement  s0,
statement  s1 
)
static

checks if there exist a conflict between s0 and s1 according to the dependency graph

in intra procedural, a store always conflicts with a return

special hook for loop statements: dependency on the index are not well generated

Definition at line 161 of file delay.c.

161  {
162  /* in intra procedural, a store always conflicts with a return */
164  ( simd_store_stat_p(s0) || simd_store_stat_p(s1) ) &&
166  return true;
167 
168  /* special hook for loop statements: dependency on the index are not well generated */
169  if(statement_loop_p(s1)) {
171  set re = get_referenced_entities(s0);
172  bool conflict = set_belong_p(re,index);
173  set_free(re);
174  return conflict;
175  }
176 
183  return true;
184  }
185  }
186  }
187  }
188  return false;
189 }
struct _newgen_struct_conflict_ * conflict
Definition: dg.h:52
bool return_statement_p(statement)
Test if a statement is a C or Fortran "return".
Definition: statement.c:172
bool set_belong_p(const set, const void *)
Definition: set.c:194
#define loop_index(x)
Definition: ri.h:1640

References delay_communications_interprocedurally_p, dependence_graph, FOREACH, get_referenced_entities(), graph_vertices, intptr_t, loop_index, return_statement_p(), s1, set_belong_p(), set_free(), simd_store_stat_p(), statement_loop(), statement_loop_p(), statement_ordering, SUCCESSOR, successor_vertex, VERTEX, vertex_successors, and vertex_to_statement().

Referenced by delay_communications_anyloop(), manage_conflicts(), and select_independent_dmas().

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

◆ statements_conflict_relaxed_p()

static bool statements_conflict_relaxed_p ( statement  s0,
statement  s1,
bool  load_p 
)
static

same as statements_conflict_p but W-* conflicts are ignored if load_p, R-* conflicts are ignored if not load_p

in intra procedural, a store always conflicts with a return

Definition at line 192 of file delay.c.

192  {
193  /* in intra procedural, a store always conflicts with a return */
195  ( simd_store_stat_p(s0) || simd_store_stat_p(s1) ) &&
197  return true;
198 
201  if(statement_ordering(s) == statement_ordering(s0) ) {
202  intptr_t expected = statement_ordering(s1) ;
206  if( (load_p && !effect_write_p(conflict_source(c))) ||
207  (!load_p && !effect_read_p(conflict_source(c))) )
208  return true;
209  }
210  }
211  }
212  }
213  }
214  return false;
215 }
#define effect_write_p(eff)
#define effect_read_p(eff)
#define effect_scalar_p(eff) entity_scalar_p(effect_entity(eff))

References CONFLICT, conflict_source, delay_communications_interprocedurally_p, dependence_graph, dg_arc_label_conflicts, effect_read_p, effect_write_p, FOREACH, graph_vertices, intptr_t, return_statement_p(), s1, simd_store_stat_p(), statement_ordering, SUCCESSOR, successor_arc_label, successor_vertex, VERTEX, vertex_successors, and vertex_to_statement().

Referenced by do_recurse_statements_conflict_p().

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

◆ translate_arguments()

static statement translate_arguments ( call  ca,
statement  s 
)
static

Definition at line 484 of file delay.c.

484  {
485  statement new = copy_statement(s);
487  pips_assert("as many parameters as formal arguments\n",gen_length(call_arguments(ca)) == gen_length(fp));
488  for(list aiter = call_arguments(ca), piter=fp;
489  !ENDP(aiter);
490  POP(aiter),POP(piter)) {
491  expression arg = EXPRESSION(CAR(aiter));
492  entity fe = ENTITY(CAR(piter));
493  replace_entity_by_expression(new,fe,arg);// this perform the formal / effective parameter substitution
494  }
495  gen_free_list(fp);
496  return new;
497 }
void replace_entity_by_expression(void *s, entity ent, expression exp)
replace all reference to entity ent by expression exp in s.
Definition: replace.c:220
list module_formal_parameters(entity func)
list module_formal_parameters(entity func) input : an entity representing a function.
Definition: module.c:327
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define call_arguments(x)
Definition: ri.h:711

References call_arguments, CAR, copy_statement(), ENDP, ENTITY, EXPRESSION, gen_free_list(), gen_length(), get_current_module_entity(), module_formal_parameters(), pips_assert, POP, and replace_entity_by_expression().

Referenced by do_delay_communications_interprocedurally().

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

Variable Documentation

◆ __delay_communications_patch_properties

bool __delay_communications_patch_properties
static

Definition at line 588 of file delay.c.

Referenced by delay_communications_init(), and delay_communications_reset().

◆ delay_communications_interprocedurally_p

◆ dependence_graph