PIPS
ikernels.c File Reference

kernels manipulation More...

#include <ctype.h>
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "kernel_memory_mapping.h"
#include "effects.h"
#include "ri-util.h"
#include "prettyprint.h"
#include "workspace-util.h"
#include "semantics.h"
#include "effects-util.h"
#include "text.h"
#include "pipsdbm.h"
#include "resources.h"
#include "properties.h"
#include "misc.h"
#include "control.h"
#include "callgraph.h"
#include "effects-generic.h"
#include "effects-simple.h"
#include "effects-convex.h"
#include "text-util.h"
#include "parser_private.h"
#include "preprocessor.h"
#include "transformer.h"
#include "accel-util.h"
+ Include dependency graph for ikernels.c:

Go to the source code of this file.

Macros

#define INIT_STATEMENT_SIZE   20
 
#define INIT_ENTITY_SIZE   10
 
#define MAKE_SET()   (set_make( set_pointer ))
 Macro to create set. More...
 
#define COPY_FROM_IN(st)   ((set)hash_get(copies_from_in, (char *)st))
 
#define COPY_FROM_OUT(st)   ((set)hash_get(copies_from_out, (char *)st))
 
#define COPY_TO_IN(st)   ((set)hash_get(copies_to_in, (char *)st))
 
#define COPY_TO_OUT(st)   ((set)hash_get(copies_to_out, (char *)st))
 
#define TABLE_FREE(t)    {HASH_MAP( k, v, {set_free( (set)v ) ;}, t ) ; hash_table_free(t);}
 

Functions

static expression makeTransfertSizeExpression (entity e)
 Make a sizeof expression. More...
 
static const char * get_dma_name (enum region_to_dma_switch m, int d)
 converts a region_to_dma_switch to corresponding dma name according to properties More...
 
static statement make_dma_transfert (entity e, enum region_to_dma_switch dma)
 
void dump_entity_set (set s)
 ikernels.c More...
 
static bool force_renormalize (expression e)
 Should be useful, but for some bullshit reason the array dimensions even for simple case like a[512][512] might be previously normalized "COMPLEX" This occurs in some special cases... More...
 
static void force_renormalize_rwt (expression e)
 
static bool array_must_fully_written_by_regions_p (entity e_used, list lreg)
 Check that an array is fully written by an exact W region in a list. More...
 
static set interprocedural_mapping (string res, call c)
 Translate the interprocedural summary for a function into a set of local corresponding parameters (entity only) More...
 
bool is_a_kernel (const char *func_name)
 
static void init_one_statement (statement st)
 
static void copy_from_statement (statement st)
 
static void copy_from_block (statement st, cons *sts)
 
static void copy_from_test (statement st, test t)
 
static void copy_from_all_kind_of_loop (statement st, statement body)
 
static void copy_from_loop (statement st, loop l)
 
static void copy_from_whileloop (statement st, whileloop l)
 
static void copy_from_forloop (statement st, forloop l)
 
static void copy_from_call (statement st, call c)
 
static void copy_from_unstructured (_UNUSED_ statement st, _UNUSED_ unstructured u)
 
static void copy_to_statement (statement st)
 
static void copy_to_block (statement st, list sts)
 
static void copy_to_test (statement st, test t)
 
static void copy_to_all_kind_of_loop (statement st, statement body)
 
static void copy_to_loop (statement st, loop l)
 
static void copy_to_whileloop (statement st, whileloop l)
 
static void copy_to_forloop (statement st, forloop l)
 
static void copy_to_call (statement st, call c)
 
static void copy_to_unstructured (_UNUSED_ statement st, _UNUSED_ unstructured u)
 
static void get_written_entities (statement s, set written_entities)
 
static void transfert_statement (statement st, set already_transfered_to, set already_transfered_from, set array_to_transfer_to_after, set array_to_transfer_from_before)
 
static void transfert_block (_UNUSED_ statement st, list sts, set already_transfered, set already_transfered_from)
 
static void transfert_test (_UNUSED_ statement st, test t, set already_transfered, set already_transfered_from, set transfert_to, set transfert_from)
 
static void transfert_loop (_UNUSED_ statement st, loop l, set already_transfered, set already_transfered_from, set transfert_to, set transfert_from)
 
static void transfert_whileloop (_UNUSED_ statement st, whileloop l, set already_transfered, set already_transfered_from, set transfert_to, set transfert_from)
 
static void transfert_forloop (_UNUSED_ statement st, forloop l, set already_transfered, set already_transfered_from, set transfert_to, set transfert_from)
 
static void transfert_call (_UNUSED_ statement st, _UNUSED_ call c, _UNUSED_ set already_transfered, _UNUSED_ set already_transfered_from)
 
static void transfert_unstructured (_UNUSED_ statement st, _UNUSED_ unstructured u, _UNUSED_ set already_transfered, _UNUSED_ set already_transfered_from)
 
bool ikernel_load_store (__attribute__((unused)) char *module_name)
 
bool kernel_data_mapping (char *module_name)
 
static void wrap_argument (syntax s)
 
static void wrap_call_argument (call c, const char *module_name)
 
bool wrap_kernel_argument (char *module_name)
 This pass will wrap kernel arguments in a call to a wrapper function. More...
 

Variables

static hash_table copies_from_in
 copy_from_in maps each statement to the "copy from" data that are in-coming the statement More...
 
static hash_table copies_from_out
 copy_from_out maps each statement to the "copy from" data that are out-going from the statement More...
 
static hash_table copies_to_in
 copy_to_in maps each statement to the "copy to" data that are in-coming the statement More...
 
static hash_table copies_to_out
 copy_to_out maps each statement to the "copy to" data that are out-going from the statement More...
 
static entity wrapper_function = NULL
 

Detailed Description

kernels manipulation

Author
Mehdi Amini mehdi.nosp@m..ami.nosp@m.ni@hp.nosp@m.c-pr.nosp@m.oject.nosp@m..com

Definition in file ikernels.c.

Macro Definition Documentation

◆ COPY_FROM_IN

#define COPY_FROM_IN (   st)    ((set)hash_get(copies_from_in, (char *)st))

Definition at line 151 of file ikernels.c.

◆ COPY_FROM_OUT

#define COPY_FROM_OUT (   st)    ((set)hash_get(copies_from_out, (char *)st))

Definition at line 166 of file ikernels.c.

◆ COPY_TO_IN

#define COPY_TO_IN (   st)    ((set)hash_get(copies_to_in, (char *)st))

Definition at line 181 of file ikernels.c.

◆ COPY_TO_OUT

#define COPY_TO_OUT (   st)    ((set)hash_get(copies_to_out, (char *)st))

Definition at line 196 of file ikernels.c.

◆ INIT_ENTITY_SIZE

#define INIT_ENTITY_SIZE   10

Definition at line 142 of file ikernels.c.

◆ INIT_STATEMENT_SIZE

#define INIT_STATEMENT_SIZE   20

Definition at line 141 of file ikernels.c.

◆ MAKE_SET

#define MAKE_SET ( )    (set_make( set_pointer ))

Macro to create set.

Definition at line 145 of file ikernels.c.

◆ TABLE_FREE

#define TABLE_FREE (   t)     {HASH_MAP( k, v, {set_free( (set)v ) ;}, t ) ; hash_table_free(t);}

Function Documentation

◆ array_must_fully_written_by_regions_p()

static bool array_must_fully_written_by_regions_p ( entity  e_used,
list  lreg 
)
static

Check that an array is fully written by an exact W region in a list.

Definition at line 238 of file ikernels.c.

238  {
239  // Ugly hack :-(
241 
242  // Force re-normalization of expression, this is a hack !
244  if(type_variable_p(entity_type(e_used))) {
245  // I don't understand why the gen_recurse doesn't work, so here is the hack for the hack...
249  }
250  }
251 
252  //
257 
258  ifdebug(6) {
259  pips_debug(6,"Array region is : ");
261  }
262  FOREACH(effect, reg, lreg) {
263  if(!descriptor_convex_p(effect_descriptor(reg))) continue;
264  // Proj region over PHI to remove precondition variables
265  // FIXME : Can be done by difference between the 2 bases
266  list proj = base_to_list(sc_base(descriptor_convex(effect_descriptor(reg))));
267  list l_phi = NIL;
269  pips_assert("expression_reference_p", expression_reference_p(e));
272  }
273 
274 
276 
277 
278  ifdebug(6) {
279  pips_debug(6,"Evaluating region : ");
280  print_region(reg);
281  }
282  if(effect_write_p(reg) && store_effect_p(reg) && region_exact_p(reg)) {
283  list ldiff = region_sup_difference(array,reg);
284  bool empty=true;
285  FOREACH(effect, diff, ldiff) {
286  if( !region_empty_p(diff)) {
287  ifdebug(6) {
288  pips_debug(6,"Diff is not empty :");
289  print_region(diff);
290  }
291  empty = false;
292  break;
293  } else {
294  ifdebug(6) {
295  pips_debug(6,"Diff is empty !\n");
296  }
297  }
298  }
299  if(empty) {
300  return true;
301  }
302  }
303  }
304  return false;
305 }
approximation make_approximation_exact(void)
Definition: effects.c:185
#define region_empty_p(reg)
#define region_exact_p(reg)
list region_sup_difference(region reg1, region reg2)
list region_sup_difference(effect reg1, reg2) input : two regions output : a list of regions containi...
effect entity_whole_region(entity, action)
Psysteme entity_declaration_sc(entity)
void region_exact_projection_along_variables(effect, list)
void region_exact_projection_along_variables(effect reg, list l_var) input : a region and a list of v...
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define effect_write_p(eff)
action make_action_write_memory(void)
To ease the extension of action with action_kind.
Definition: effects.c:1011
bool store_effect_p(effect)
Definition: effects.c:1062
#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 effect_approximation(x)
Definition: effects.h:644
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
void gen_remove(list *cpp, const void *o)
remove all occurences of item o from list *cpp, which is thus modified.
Definition: list.c:685
#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
#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
list base_to_list(Pbase base)
Most includes are centralized here.
static bool force_renormalize(expression e)
Should be useful, but for some bullshit reason the array dimensions even for simple case like a[512][...
Definition: ikernels.c:221
static void force_renormalize_rwt(expression e)
Definition: ikernels.c:231
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define print_region(x)
Definition: print.c:343
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154
#define reference_variable(x)
Definition: ri.h:2326
#define dimension_lower(x)
Definition: ri.h:980
#define type_variable(x)
Definition: ri.h:2949
#define dimension_upper(x)
Definition: ri.h:982
#define reference_indices(x)
Definition: ri.h:2328
#define variable_dimensions(x)
Definition: ri.h:3122
#define entity_type(x)
Definition: ri.h:2792
#define type_variable_p(x)
Definition: ri.h:2947
Psysteme sc_safe_append(Psysteme s1, Psysteme s2)
Psysteme sc_safe_append(Psysteme s1, Psysteme s2) input : output : calcul de l'intersection des polye...
Psysteme sc_safe_normalize(Psysteme ps)
Psysteme sc_safe_normalize(Psysteme ps) output : ps, normalized.
#define ifdebug(n)
Definition: sg.c:47
static entity array
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
@ empty
b1 < bj -> h1/hj = empty
Definition: union-local.h:64

References array, base_to_list(), CONS, descriptor_convex, descriptor_convex_p, dimension_lower, dimension_upper, effect_any_reference, effect_approximation, effect_descriptor, effect_write_p, empty, entity_declaration_sc(), entity_type, entity_whole_region(), expression_domain, expression_reference(), expression_reference_p(), force_renormalize(), force_renormalize_rwt(), FOREACH, gen_recurse, gen_remove(), ifdebug, make_action_write_memory(), make_approximation_exact(), NIL, pips_assert, pips_debug, print_region, reference_indices, reference_variable, region_empty_p, region_exact_p, region_exact_projection_along_variables(), region_sup_difference(), sc_safe_append(), sc_safe_normalize(), store_effect_p(), type_variable, type_variable_p, and variable_dimensions.

Referenced by copy_to_call().

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

◆ copy_from_all_kind_of_loop()

static void copy_from_all_kind_of_loop ( statement  st,
statement  body 
)
static

Compute "in" sets for the loop body

Compute loop body

Fix point

Compute "out" sets for the loop

Body is always done at least one time

Body is not always done

Definition at line 448 of file ikernels.c.

448  {
449  /* Compute "in" sets for the loop body */
450  set_assign(COPY_FROM_IN( body ), COPY_FROM_IN( st ));
451 
452  /* Compute loop body */
453  copy_from_statement(body);
454 
455  /* Fix point */
456  /*
457  if(!set_equal_p(COPY_FROM_IN( body ),set_intersection(COPY_FROM_IN( st ),
458  COPY_FROM_OUT( body ),
459  COPY_FROM_IN( st )))) {
460  return copy_from_all_kind_of_loop(st,body);
461  }
462  */
463 
464  /* Compute "out" sets for the loop */
465  if(true) { //loop_executed_once_p(st, l)) { FIXME !!!!
466  pips_debug(1,"Loop executed once !\n");
467  /* Body is always done at least one time */
468  set_assign(COPY_FROM_OUT( st ), COPY_FROM_OUT( body ));
469  } else {
470  pips_debug(1,"Loop not executed once :-( !\n");
471  /* Body is not always done */
473  COPY_FROM_OUT( body ),
474  COPY_FROM_IN( st ));
475  }
476 
477 }
static void copy_from_statement(statement st)
Definition: ikernels.c:580
#define COPY_FROM_OUT(st)
Definition: ikernels.c:166
#define COPY_FROM_IN(st)
Definition: ikernels.c:151
set set_intersection(set, const set, const set)
Definition: set.c:229
set set_assign(set, const set)
Assign a set with the content of another set.
Definition: set.c:129

References COPY_FROM_IN, COPY_FROM_OUT, copy_from_statement(), pips_debug, set_assign(), and set_intersection().

Referenced by copy_from_forloop(), copy_from_loop(), and copy_from_whileloop().

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

◆ copy_from_block()

static void copy_from_block ( statement  st,
cons sts 
)
static

The initial in for the block

loop over statements inside the block

propagate "in" sets

Compute the "copy from" for this statement

Get the ins for next statement

The outs for the whole block

Definition at line 392 of file ikernels.c.

392  {
393  /* The initial in for the block */
394  set copy_from_in = COPY_FROM_IN( st );
395  /* loop over statements inside the block */
396  FOREACH( statement, one, sts ) {
397  /* propagate "in" sets */
398  set_assign(COPY_FROM_IN( one ), copy_from_in);
399 
400  /* Compute the "copy from" for this statement */
401  copy_from_statement(one);
402 
403  /* Get the ins for next statement */
404  copy_from_in = COPY_FROM_OUT( one );
405  }
406 
407  /* The outs for the whole block */
408  set_assign(COPY_FROM_OUT( st ), copy_from_in);
409 
410 }
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59

References COPY_FROM_IN, COPY_FROM_OUT, copy_from_statement(), FOREACH, and set_assign().

Referenced by copy_from_statement().

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

◆ copy_from_call()

static void copy_from_call ( statement  st,
call  c 
)
static

The initial in

The outs is initially the in

Definition at line 512 of file ikernels.c.

512  {
514  const char* func_name = entity_local_name(callee);
515 
516  /* The initial in */
517  set copy_from_in = COPY_FROM_IN( st );
518  set copy_from_out = COPY_FROM_OUT( st );
519 
520  /* The outs is initially the in */
521  set_assign(copy_from_out, copy_from_in);
522  if(is_a_kernel(func_name)) {
523  pips_debug(3,"%s is a Kernel !\n",
524  func_name);
525  // it's a kernel call !!
526  // Let's add the "region out" to copy_from set !
527  list l_out = load_statement_out_regions(st);
528  FOREACH(EFFECT, eff, l_out )
529  {
531  if(entity_array_p(e_used)) {
532  copy_from_out = set_add_element(copy_from_out, copy_from_out, e_used);
533  }
534  }
535  } else {
536  // Standard call (not a kernel)
537  pips_debug(3,"%s is a simple call\n",
538  func_name);
539 
540 
541  // We get the inter-procedural results for copy in
542  set at_call_site;
543  if(user_call_p(c)) { // Ignoring intrinsics
544  at_call_site = interprocedural_mapping(DBR_KERNEL_COPY_IN,c);
545  } else
546  at_call_site = set_make(set_pointer);
547 
548  // We remove from "copy from" what is used by this statement but not what's
549  // in copy-in
552  if(entity_array_p(e_used) && !set_belong_p(at_call_site,e_used)) {
553  pips_debug(6,"Removing %s from copy_out\n",entity_name(e_used));
554  copy_from_out = set_del_element(copy_from_out, copy_from_out, e_used);
555  }
556  }
557 
558  // No longer used
559  set_free(at_call_site);
560 
561  // We add the inter-procedural results for copy out, but not for intrinsics
562  if(user_call_p(c)) { // Ignoring intrinsics
563  at_call_site = interprocedural_mapping(DBR_KERNEL_COPY_OUT,c);
564  copy_from_out = set_union(copy_from_out, at_call_site, copy_from_out);
565  ifdebug(6) {
566  pips_debug(6,"Adding interprocedural summary : ");
567  print_entities(set_to_list(at_call_site));
568  fprintf(stderr,"\n");
569  }
570  set_free(at_call_site);
571  }
572  }
573 }
static entity callee
Definition: alias_pairs.c:62
list load_proper_rw_effects_list(statement)
list load_statement_out_regions(statement)
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
static set interprocedural_mapping(string res, call c)
Translate the interprocedural summary for a function into a set of local corresponding parameters (en...
Definition: ikernels.c:311
bool is_a_kernel(const char *func_name)
Definition: ikernels.c:369
set set_del_element(set, const set, const void *)
Definition: set.c:265
list set_to_list(const set)
create a list from a set the set is not freed
Definition: set.c:436
void set_free(set)
Definition: set.c:332
bool set_belong_p(const set, const void *)
Definition: set.c:194
set set_union(set, const set, const set)
Definition: set.c:211
@ 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
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
bool entity_array_p(entity e)
Is e a variable with an array type?
Definition: entity.c:754
void print_entities(list l)
Definition: entity.c:167
bool user_call_p(call c)
Test if a call is a user call.
Definition: expression.c:4361
#define call_function(x)
Definition: ri.h:709
#define entity_name(x)
Definition: ri.h:2790
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...

References call_function, callee, COPY_FROM_IN, COPY_FROM_OUT, EFFECT, effect_any_reference, entity_array_p(), entity_local_name(), entity_name, FOREACH, fprintf(), ifdebug, interprocedural_mapping(), is_a_kernel(), load_proper_rw_effects_list(), load_statement_out_regions(), pips_debug, print_entities(), reference_variable, set_add_element(), set_assign(), set_belong_p(), set_del_element(), set_free(), set_make(), set_pointer, set_to_list(), set_union(), and user_call_p().

Referenced by copy_from_statement().

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

◆ copy_from_forloop()

static void copy_from_forloop ( statement  st,
forloop  l 
)
static

Definition at line 507 of file ikernels.c.

507  {
508  statement body = forloop_body(l);
509  copy_from_all_kind_of_loop(st, body);
510 }
static void copy_from_all_kind_of_loop(statement st, statement body)
Definition: ikernels.c:448
#define forloop_body(x)
Definition: ri.h:1372

References copy_from_all_kind_of_loop(), and forloop_body.

Referenced by copy_from_statement().

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

◆ copy_from_loop()

static void copy_from_loop ( statement  st,
loop  l 
)
static

Definition at line 479 of file ikernels.c.

479  {
480  statement body = loop_body(l);
481  copy_from_all_kind_of_loop(st, body);
482 
483  /*
484  * For further "already_transfered" optimization to be correct !
485  * We have to force to transfert from the accelerator in the body of the loop
486  * if we can't know that the data won't be used on the CPU at the begin of the
487  * next iteration
488  * see validation/Gpu/Comm_optimization.sub/loop01.c
489  */
490  set to_delete = MAKE_SET();
492  if(!set_belong_p(COPY_TO_IN(st),e)) {
493  //insert_statement(body,make_dma_transfert(e,dma_store),false);
494  pips_debug(1,"Removing %s from loop copy-out !\n",entity_name(e));
495  set_add_element(to_delete,to_delete,e);
496  }
497  }
498  set_difference(COPY_FROM_OUT(st),COPY_FROM_OUT(st),to_delete);
499  set_difference(COPY_FROM_OUT(body),COPY_FROM_OUT(body),to_delete);
500  set_free(to_delete);
501 
502 }
#define MAKE_SET()
Macro to create set.
Definition: ikernels.c:145
#define COPY_TO_IN(st)
Definition: ikernels.c:181
set set_difference(set, const set, const set)
Definition: set.c:256
#define SET_FOREACH(type_name, the_item, the_set)
enumerate set elements in their internal order.
Definition: newgen_set.h:78
#define loop_body(x)
Definition: ri.h:1644

References copy_from_all_kind_of_loop(), COPY_FROM_OUT, COPY_TO_IN, entity_name, loop_body, MAKE_SET, pips_debug, set_add_element(), set_belong_p(), set_difference(), SET_FOREACH, and set_free().

Referenced by copy_from_statement().

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

◆ copy_from_statement()

static void copy_from_statement ( statement  st)
static

Compute "copy from" sets for the instruction : recursion

Definition at line 580 of file ikernels.c.

580  {
581  instruction i;
582 
583  /* Compute "copy from" sets for the instruction : recursion */
584  switch(instruction_tag( i = statement_instruction( st ))) {
587  break;
588  case is_instruction_test:
590  break;
591  case is_instruction_loop:
593  break;
596  break;
599  break;
600  case is_instruction_call:
602  break;
605  if(expression_call_p(e)) {
607  } else {
608  pips_user_warning("Unsupported stmt expression : ");
609  print_expression(e);
610  fprintf(stderr,"\n");
611  // Just propagate then...
612  set copy_from_in = COPY_FROM_IN( st );
613  set copy_from_out = COPY_FROM_OUT( st );
614  set_assign(copy_from_out, copy_from_in);
615  }
616  break;
617  }
618  case is_instruction_goto:
619  pips_internal_error("Unexpected tag %d\n", i);
620  break;
623  break;
624  default:
625  pips_internal_error("Unknown tag %d\n", instruction_tag(i) );
626  }
627 
628  ifdebug(4) {
629  fprintf(stderr,
630  "** stmt (%d) associated copy from : **\n",
631  (int)statement_ordering(st));
632  fprintf(stderr, "*\n* OUT : ");
633  {
634  string str = concatenate("Copy from out : ", NULL);
636  FOREACH(entity, e, t_from) {
637  fprintf(stderr, "%s ", entity_name(e));
638  str = concatenate(str, " ", entity_local_name(e), NULL);
639  }
640  str = concatenate(str, "\n", NULL);
643  }
644  fprintf(stderr, "*\n**********************************\n");
645 
646  fprintf(stderr, "* IN : ");
647  {
648  string str = concatenate("Copy from in : ", NULL);
650  FOREACH(entity, e, t_from) {
651  fprintf(stderr, "%s ", entity_name(e));
652  str = concatenate(str, " ", entity_local_name(e), NULL);
653  }
654  str = concatenate(str, "\n", NULL);
657  }
658  fprintf(stderr, "*\n**********************************\n");
659  }
660 
661 }
bool empty_statement_or_continue_without_comment_p(statement)
Return true if the statement is an empty instruction block or a continue without comments or without ...
Definition: statement.c:497
void insert_comments_to_statement(statement, const char *)
Insert a comment string (if non empty) at the beginning of the comments of a statement.
Definition: statement.c:1916
static void copy_from_forloop(statement st, forloop l)
Definition: ikernels.c:507
static void copy_from_whileloop(statement st, whileloop l)
Definition: ikernels.c:503
static void copy_from_test(statement st, test t)
Definition: ikernels.c:411
static void copy_from_call(statement st, call c)
Definition: ikernels.c:512
static void copy_from_unstructured(_UNUSED_ statement st, _UNUSED_ unstructured u)
Definition: ikernels.c:575
static void copy_from_block(statement st, cons *sts)
Definition: ikernels.c:392
static void copy_from_loop(statement st, loop l)
Definition: ikernels.c:479
#define pips_user_warning
Definition: misc-local.h:146
#define pips_internal_error
Definition: misc-local.h:149
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
list set_to_sorted_list(const set, gen_cmp_func_t)
Definition: set.c:447
int(* gen_cmp_func_t)(const void *, const void *)
Definition: newgen_types.h:114
void print_expression(expression e)
no file descriptor is passed to make is easier to use in a debugging stage.
Definition: expression.c:58
#define statement_block_p(stat)
#define is_instruction_block
soft block->sequence transition
#define instruction_block(i)
int compare_entities(const entity *pe1, const entity *pe2)
Comparison function for qsort.
Definition: entity.c:1328
bool expression_call_p(expression e)
Definition: expression.c:415
call expression_call(expression e)
Definition: expression.c:445
#define instruction_loop(x)
Definition: ri.h:1520
#define statement_ordering(x)
Definition: ri.h:2454
@ is_instruction_goto
Definition: ri.h:1473
@ is_instruction_unstructured
Definition: ri.h:1475
@ is_instruction_whileloop
Definition: ri.h:1472
@ is_instruction_expression
Definition: ri.h:1478
@ is_instruction_test
Definition: ri.h:1470
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_forloop
Definition: ri.h:1477
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define instruction_forloop(x)
Definition: ri.h:1538
#define instruction_expression(x)
Definition: ri.h:1541
#define instruction_whileloop(x)
Definition: ri.h:1523
#define statement_instruction(x)
Definition: ri.h:2458
#define instruction_call(x)
Definition: ri.h:1529
#define instruction_test(x)
Definition: ri.h:1517
#define instruction_unstructured(x)
Definition: ri.h:1532
char * strdup()

References compare_entities(), concatenate(), copy_from_block(), copy_from_call(), copy_from_forloop(), COPY_FROM_IN, copy_from_loop(), COPY_FROM_OUT, copy_from_test(), copy_from_unstructured(), copy_from_whileloop(), empty_statement_or_continue_without_comment_p(), entity_local_name(), entity_name, expression_call(), expression_call_p(), FOREACH, fprintf(), ifdebug, insert_comments_to_statement(), instruction_block, instruction_call, instruction_expression, instruction_forloop, instruction_loop, instruction_tag, instruction_test, instruction_unstructured, instruction_whileloop, is_instruction_block, is_instruction_call, is_instruction_expression, is_instruction_forloop, is_instruction_goto, is_instruction_loop, is_instruction_test, is_instruction_unstructured, is_instruction_whileloop, pips_internal_error, pips_user_warning, print_expression(), set_assign(), set_to_sorted_list(), statement_block_p, statement_instruction, statement_ordering, and strdup().

Referenced by copy_from_all_kind_of_loop(), copy_from_block(), copy_from_test(), and kernel_data_mapping().

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

◆ copy_from_test()

static void copy_from_test ( statement  st,
test  t 
)
static

Compute true branch

Compute false branch

Compute "out" sets for the test

Definition at line 411 of file ikernels.c.

411  {
412  /* Compute true branch */
415 
416  /* Compute false branch */
419 
420 
421  /* Compute "out" sets for the test */
422  set copy_from_out = COPY_FROM_OUT( st );
423 
425 
426 
427  ifdebug(6) {
428  pips_debug(6,"Handling copy from for test expression : ");
430  fprintf(stderr,"\n");
431  pips_debug(6,"Copy from is : ");
432  print_entities(set_to_list(copy_from_out));
433  fprintf(stderr,"\n");
434  }
435 
436  // We remove from "copy from" what is used by this statement
439  if(entity_array_p(e_used)) {
440  pips_debug(6,"Removing %s from copy_out\n",entity_name(e_used));
441  set_del_element(copy_from_out, copy_from_out, e_used);
442  }
443  }
444 
445 
446 }
#define test_false(x)
Definition: ri.h:2837
#define test_true(x)
Definition: ri.h:2835
#define test_condition(x)
Definition: ri.h:2833

References COPY_FROM_IN, COPY_FROM_OUT, copy_from_statement(), EFFECT, effect_any_reference, entity_array_p(), entity_name, FOREACH, fprintf(), ifdebug, load_proper_rw_effects_list(), pips_debug, print_entities(), print_expression(), reference_variable, set_assign(), set_del_element(), set_intersection(), set_to_list(), test_condition, test_false, and test_true.

Referenced by copy_from_statement().

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

◆ copy_from_unstructured()

static void copy_from_unstructured ( _UNUSED_ statement  st,
_UNUSED_ unstructured  u 
)
static

Definition at line 575 of file ikernels.c.

575  {
576  //pips_user_warning("Unimplemented !! Results may be wrong...\n");
577  pips_user_error("Please restructure your input source code.\n");
578 }
#define pips_user_error
Definition: misc-local.h:147

References pips_user_error.

Referenced by copy_from_statement().

+ Here is the caller graph for this function:

◆ copy_from_whileloop()

static void copy_from_whileloop ( statement  st,
whileloop  l 
)
static

Definition at line 503 of file ikernels.c.

503  {
504  statement body = whileloop_body(l);
505  copy_from_all_kind_of_loop(st, body);
506 }
#define whileloop_body(x)
Definition: ri.h:3162

References copy_from_all_kind_of_loop(), and whileloop_body.

Referenced by copy_from_statement().

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

◆ copy_to_all_kind_of_loop()

static void copy_to_all_kind_of_loop ( statement  st,
statement  body 
)
static

Compute "out" sets for the loop body

Save result

Compute loop body

Fix point

Compute "in" sets for the loop

Body is always done at least one time

Body is not always done

Definition at line 728 of file ikernels.c.

728  {
729  /* Compute "out" sets for the loop body */
730  set body_out = COPY_TO_OUT(body);
731  set_union(body_out,
732  COPY_TO_OUT( st ),
733  COPY_TO_IN( body ));
734 
735  /* Save result */
736  set tmp = MAKE_SET();
737  set_assign(tmp,body_out);
738 
739  /* Compute loop body */
740  copy_to_statement(body);
741 
742  /* Fix point */
743  set_union(body_out ,
744  COPY_TO_OUT( st ),
745  COPY_TO_IN( body ));
746  if(!set_equal_p(tmp,body_out)) {
747  set_free(tmp);
748  return copy_to_all_kind_of_loop(st,body);
749  }
750  set_free(tmp);
751 
752 
753  /* Compute "in" sets for the loop */
754  if(true) { //loop_executed_once_p(st, l)) {
755  pips_debug(1,"Loop executed once !\n");
756  /* Body is always done at least one time */
757  set_assign(COPY_TO_IN( st ), COPY_TO_IN( body ));
758  } else {
759  pips_debug(1,"Loop not executed once :-( !\n");
760  /* Body is not always done */
761  set_intersection(COPY_TO_IN( st ), COPY_TO_IN( body ), COPY_TO_OUT( st ));
762  }
763 
764 
765 
766 
767 }
static void copy_to_all_kind_of_loop(statement st, statement body)
Definition: ikernels.c:728
static void copy_to_statement(statement st)
Definition: ikernels.c:863
#define COPY_TO_OUT(st)
Definition: ikernels.c:196
bool set_equal_p(const set, const set)
returns whether s1 == s2
Definition: set.c:316

References COPY_TO_IN, COPY_TO_OUT, copy_to_statement(), MAKE_SET, pips_debug, set_assign(), set_equal_p(), set_free(), set_intersection(), and set_union().

Referenced by copy_to_forloop(), copy_to_loop(), and copy_to_whileloop().

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

◆ copy_to_block()

static void copy_to_block ( statement  st,
list  sts 
)
static

The initial out for the block

loop over statements inside the block

propagate "out" sets

Compute the "copy to" for this statement

Get the outs for next statement

This is a non necessary optimisation, the set is just smaller with

The outs for the whole block

FIXME : free sts_reverse list && copy_to_out

Definition at line 669 of file ikernels.c.

669  {
670  /* The initial out for the block */
671  set copy_to_out = MAKE_SET();
672  set_assign(copy_to_out, COPY_TO_OUT( st ));
673  list sts_reverse = gen_nreverse(gen_copy_seq(sts));
674  /* loop over statements inside the block */
675  FOREACH( statement, one, sts_reverse ) {
676  /* propagate "out" sets */
677  set_assign(COPY_TO_OUT( one ), copy_to_out);
678 
679  /* Compute the "copy to" for this statement */
680  copy_to_statement(one);
681 
682  /* Get the outs for next statement */
683  set_assign(copy_to_out, COPY_TO_IN( one ));
684 
685  /* This is a non necessary optimisation, the set is just smaller with */
686 // set_difference(copy_to_out, copy_to_out, COPY_FROM_IN(one));
687  }
688 
689  /* The outs for the whole block */
690  set_assign(COPY_TO_IN( st ), copy_to_out);
691 
692  /* FIXME : free sts_reverse list && copy_to_out*/
693 
694 }
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501

References COPY_TO_IN, COPY_TO_OUT, copy_to_statement(), FOREACH, gen_copy_seq(), gen_nreverse(), MAKE_SET, and set_assign().

Referenced by copy_to_statement().

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

◆ copy_to_call()

static void copy_to_call ( statement  st,
call  c 
)
static

The initial

The ins are initially the out minus CopyFrom

Definition at line 780 of file ikernels.c.

780  {
782  const char* func_name = entity_local_name(callee);
783 
784  /* The initial */
785  set copy_to_in = COPY_TO_IN( st );
786  set copy_to_out = COPY_TO_OUT( st );
787 
788  /* The ins are initially the out minus CopyFrom*/
789  set_assign(copy_to_in, copy_to_out);
790  if(is_a_kernel(func_name)) {
791  pips_debug(3,"%s is a Kernel !\n",
792  func_name);
793  // it's a kernel call !!
794  // Let's add the "region in" and "region out" to copy_to set !
795  list l_in = load_statement_in_regions(st);
796  FOREACH(EFFECT, eff, l_in )
797  {
799  if(entity_array_p(e_used)) {
800  pips_debug(6,"Adding in %s into copy_in\n",entity_name(e_used));
801  copy_to_in = set_add_element(copy_to_in, copy_to_in, e_used);
802  }
803  }
804  list l_out = load_statement_out_regions(st);
805  FOREACH(EFFECT, eff, l_out )
806  {
808  if(entity_array_p(e_used)) {
810 
811  if(!array_must_fully_written_by_regions_p(e_used,lreg)) {
812  pips_debug(6,"Adding written %s into copy_in\n",entity_name(e_used));
813  copy_to_in = set_add_element(copy_to_in, copy_to_in, e_used);
814  } else {
815  pips_debug(6,"Do not add %s into copy_in because fully overwritten\n",
816  entity_name(e_used));
817  }
818  }
819  }
820  } else {
821  // Standard call (not a kernel)
822  pips_debug(3,"%s is a simple call\n",
823  func_name);
824  // We remove from "copy to" what is written by this statement
826 // if(effect_write_p(eff)) { BUGGY at that time ! it breaks hoisting transfers out of loop... the scheme is broken by design !
828  ifdebug(6) {
829  if(entity_array_p(e_used)) {
830  pips_debug(6,"Removing %s from copy_in\n",entity_name(e_used));
831  }
832  }
833  copy_to_in = set_del_element(copy_to_in, copy_to_in, e_used);
834 // }
835  }
836 
837 
838  // We add the inter-procedural results for copy in, but not for intrinsics
839  if(user_call_p(c)) { // Ignoring intrinsics
840  set at_call_site = interprocedural_mapping(DBR_KERNEL_COPY_IN,c);
841  copy_to_in = set_union(copy_to_in, at_call_site, copy_to_in);
842  set_free(at_call_site);
843  }
844 
845  }
846  // copy_to_in = set_difference(copy_to_in, copy_to_in, COPY_FROM_IN(st));
847 }
list load_statement_in_regions(statement)
static bool array_must_fully_written_by_regions_p(entity e_used, list lreg)
Check that an array is fully written by an exact W region in a list.
Definition: ikernels.c:238

References array_must_fully_written_by_regions_p(), call_function, callee, COPY_TO_IN, COPY_TO_OUT, EFFECT, effect_any_reference, entity_array_p(), entity_local_name(), entity_name, FOREACH, ifdebug, interprocedural_mapping(), is_a_kernel(), load_proper_rw_effects_list(), load_statement_in_regions(), load_statement_out_regions(), pips_debug, reference_variable, set_add_element(), set_assign(), set_del_element(), set_free(), set_union(), and user_call_p().

Referenced by copy_to_statement().

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

◆ copy_to_forloop()

static void copy_to_forloop ( statement  st,
forloop  l 
)
static

Definition at line 776 of file ikernels.c.

776  {
777  statement body = forloop_body(l);
778  copy_to_all_kind_of_loop(st, body);
779 }

References copy_to_all_kind_of_loop(), and forloop_body.

Referenced by copy_to_statement().

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

◆ copy_to_loop()

static void copy_to_loop ( statement  st,
loop  l 
)
static

Definition at line 768 of file ikernels.c.

768  {
769  statement body = loop_body(l);
770  copy_to_all_kind_of_loop(st, body);
771 }

References copy_to_all_kind_of_loop(), and loop_body.

Referenced by copy_to_statement().

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

◆ copy_to_statement()

static void copy_to_statement ( statement  st)
static

Compute "copy from" sets for the instruction : recursion

The ins are initially the out minus CopyFrom

Definition at line 863 of file ikernels.c.

863  {
864  instruction i;
865 
866  /* Compute "copy from" sets for the instruction : recursion */
867  switch(instruction_tag( i = statement_instruction( st ))) {
870  break;
871  case is_instruction_test:
872  copy_to_test(st, instruction_test( i ));
873  break;
874  case is_instruction_loop:
875  copy_to_loop(st, instruction_loop( i ));
876  break;
879  break;
882  break;
883  case is_instruction_call:
884  copy_to_call(st, instruction_call( i ));
885  break;
888  if(expression_call_p(e)) {
890  } else {
891  pips_user_warning("Unsupported stmt expression : ");
892  print_expression(e);
893  fprintf(stderr,"\n");
894  // Just propagate then...
895  set copy_to_in = COPY_TO_IN( st );
896  set copy_to_out = COPY_TO_OUT( st );
897  /* The ins are initially the out minus CopyFrom*/
898  set_assign(copy_to_in, copy_to_out);
899  }
900  break;
901  }
902  case is_instruction_goto:
903  pips_internal_error("Unexpected instruction tag %d\n", i);
904  break;
907  break;
908  default:
909  pips_internal_error("Unknown tag %d\n", instruction_tag(i) );
910  }
911 
912 
913  // We remove from "copy to out" what is not written by this statement
914  set allowed_to_copy_to= MAKE_SET();
915  gen_context_recurse(st, allowed_to_copy_to,
917  ifdebug(4) {
918  pips_debug(4,"Removing from copy_to_out what is not written here : ");
919  set removed = MAKE_SET();
920  set_difference(removed,COPY_TO_OUT(st),allowed_to_copy_to);
922  FOREACH(entity, e, t_to) {
923  fprintf(stderr, "%s ", entity_name(e));
924  }
925  fprintf(stderr, "\n");
926  }
927  set_intersection(COPY_TO_OUT(st),COPY_TO_OUT(st),allowed_to_copy_to);
928  set_free(allowed_to_copy_to);
929 
930 
931  ifdebug(4) {
932  fprintf(stderr,
933  "** stmt (%d) associated copy to : **\n",
934  (int)statement_ordering(st));
935  fprintf(stderr, "*\n* OUT : ");
936  {
937  string str = concatenate("Copy to out : ", NULL);
939  FOREACH(entity, e, t_to) {
940  fprintf(stderr, "%s ", entity_name(e));
941  str = concatenate(str, " ", entity_local_name(e), NULL);
942  }
943  str = concatenate(str, "\n", NULL);
946  }
947  fprintf(stderr, "* IN : ");
948  {
949  string str = concatenate("Copy to in : ", NULL);
951  FOREACH(entity, e, t_to) {
952  fprintf(stderr, "%s ", entity_name(e));
953  str = concatenate(str, " ", entity_local_name(e), NULL);
954  }
955  str = concatenate(str, "\n", NULL);
958  }
959  fprintf(stderr, "*\n**********************************\n");
960  }
961 
962 
963 }
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
Definition: genC.h:285
bool gen_true2(__attribute__((unused)) gen_chunk *u1, __attribute__((unused)) void *u2)
Definition: genClib.c:2785
static void get_written_entities(statement s, set written_entities)
Definition: ikernels.c:854
static void copy_to_whileloop(statement st, whileloop l)
Definition: ikernels.c:772
static void copy_to_block(statement st, list sts)
Definition: ikernels.c:669
static void copy_to_call(statement st, call c)
Definition: ikernels.c:780
static void copy_to_forloop(statement st, forloop l)
Definition: ikernels.c:776
static void copy_to_test(statement st, test t)
Definition: ikernels.c:695
static void copy_to_unstructured(_UNUSED_ statement st, _UNUSED_ unstructured u)
Definition: ikernels.c:849
static void copy_to_loop(statement st, loop l)
Definition: ikernels.c:768
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362

References compare_entities(), concatenate(), copy_to_block(), copy_to_call(), copy_to_forloop(), COPY_TO_IN, copy_to_loop(), COPY_TO_OUT, copy_to_test(), copy_to_unstructured(), copy_to_whileloop(), empty_statement_or_continue_without_comment_p(), entity_local_name(), entity_name, expression_call(), expression_call_p(), FOREACH, fprintf(), gen_context_recurse, gen_true2(), get_written_entities(), ifdebug, insert_comments_to_statement(), instruction_block, instruction_call, instruction_expression, instruction_forloop, instruction_loop, instruction_tag, instruction_test, instruction_unstructured, instruction_whileloop, is_instruction_block, is_instruction_call, is_instruction_expression, is_instruction_forloop, is_instruction_goto, is_instruction_loop, is_instruction_test, is_instruction_unstructured, is_instruction_whileloop, MAKE_SET, pips_debug, pips_internal_error, pips_user_warning, print_expression(), set_assign(), set_difference(), set_free(), set_intersection(), set_to_sorted_list(), statement_block_p, statement_domain, statement_instruction, statement_ordering, and strdup().

Referenced by copy_to_all_kind_of_loop(), copy_to_block(), copy_to_test(), and kernel_data_mapping().

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

◆ copy_to_test()

static void copy_to_test ( statement  st,
test  t 
)
static

Compute true branch

Compute false branch

Compute "in" sets for the test

Definition at line 695 of file ikernels.c.

695  {
696  /* Compute true branch */
699 
700  /* Compute false branch */
703 
704 
705  /* Compute "in" sets for the test */
706  set copy_to_in = COPY_TO_IN( st );
707 
709 
710  ifdebug(6) {
711  pips_debug(6,"Handling copy to for test expression : ");
713  fprintf(stderr,"\n");
714  }
715 
716  // We remove from "copy to" what is used by the test condition
719  if(entity_array_p(e_used)) {
720  pips_debug(6,"Removing %s from copy_in\n",entity_name(e_used));
721  set_del_element(copy_to_in, copy_to_in, e_used);
722  }
723  }
724 
725 
726 
727 }

References COPY_TO_IN, COPY_TO_OUT, copy_to_statement(), EFFECT, effect_any_reference, entity_array_p(), entity_name, FOREACH, fprintf(), ifdebug, load_proper_rw_effects_list(), pips_debug, print_expression(), reference_variable, set_assign(), set_del_element(), set_intersection(), test_condition, test_false, and test_true.

Referenced by copy_to_statement().

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

◆ copy_to_unstructured()

static void copy_to_unstructured ( _UNUSED_ statement  st,
_UNUSED_ unstructured  u 
)
static

Definition at line 849 of file ikernels.c.

849  {
850  //pips_user_warning("Unimplemented !! Results may be wrong...\n");
851  pips_user_error("Please restructure your source code.\n");
852 }

References pips_user_error.

Referenced by copy_to_statement().

+ Here is the caller graph for this function:

◆ copy_to_whileloop()

static void copy_to_whileloop ( statement  st,
whileloop  l 
)
static

Definition at line 772 of file ikernels.c.

772  {
773  statement body = whileloop_body(l);
774  copy_to_all_kind_of_loop(st, body);
775 }

References copy_to_all_kind_of_loop(), and whileloop_body.

Referenced by copy_to_statement().

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

◆ dump_entity_set()

void dump_entity_set ( set  s)

ikernels.c

Definition at line 209 of file ikernels.c.

209  {
210  SET_FOREACH(entity, e, s) {
211  fprintf(stderr,"%s,",entity_name(e));
212  }
213  fprintf(stderr,"\n");
214 }

References entity_name, fprintf(), and SET_FOREACH.

+ Here is the call graph for this function:

◆ force_renormalize()

static bool force_renormalize ( expression  e)
static

Should be useful, but for some bullshit reason the array dimensions even for simple case like a[512][512] might be previously normalized "COMPLEX" This occurs in some special cases...

Definition at line 221 of file ikernels.c.

221  {
223  // Remove a warning
226  }
228  return true;
229 }
void free_normalized(normalized p)
Definition: ri.c:1407
normalized NormalizeExpression(expression e)
normalize.c
Definition: normalize.c:81
#define normalized_undefined
Definition: ri.h:1745
#define expression_normalized(x)
Definition: ri.h:1249
#define normalized_undefined_p(x)
Definition: ri.h:1746

References expression_normalized, free_normalized(), normalized_undefined, normalized_undefined_p, and NormalizeExpression().

Referenced by array_must_fully_written_by_regions_p(), and force_renormalize_rwt().

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

◆ force_renormalize_rwt()

static void force_renormalize_rwt ( expression  e)
static

Definition at line 231 of file ikernels.c.

231  {
232  (void) force_renormalize(e);
233 }

References force_renormalize().

Referenced by array_must_fully_written_by_regions_p().

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

◆ get_dma_name()

static const char* get_dma_name ( enum region_to_dma_switch  m,
int  d 
)
static

converts a region_to_dma_switch to corresponding dma name according to properties

If the DMA is not scalar, the DMA function name is in the property of the form KERNEL_LOAD_STORE_LOAD/STORE_FUNCTION_dD:

Definition at line 92 of file ikernels.c.

92  {
93  char *seeds[] = { "KERNEL_LOAD_STORE_LOAD_FUNCTION",
94  "KERNEL_LOAD_STORE_STORE_FUNCTION",
95  "KERNEL_LOAD_STORE_ALLOCATE_FUNCTION",
96  "KERNEL_LOAD_STORE_DEALLOCATE_FUNCTION" };
97  const char * propname = seeds[(int)m];
98  /* If the DMA is not scalar, the DMA function name is in the property
99  of the form KERNEL_LOAD_STORE_LOAD/STORE_FUNCTION_dD: */
100  char * apropname=NULL;
101  if(d > 0 && (int)m < 2)
102  asprintf(&apropname, "%s_%dD", seeds[(int)m], (int)d);
103  const char* dmaname = get_string_property(propname);
104  if(apropname)
105  free(apropname);
106  pips_debug(6,"Get dma name : %s\n",dmaname);
107  return dmaname;
108 }
void const char const char const int
char * get_string_property(const char *)
void free(void *)
#define asprintf
Definition: misc-local.h:225

References asprintf, free(), get_string_property(), int, and pips_debug.

Referenced by make_dma_transfert().

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

◆ get_written_entities()

static void get_written_entities ( statement  s,
set  written_entities 
)
static

Definition at line 854 of file ikernels.c.

854  {
856  if(effect_write_p(eff) && store_effect_p(eff)) {
858  set_add_element(written_entities,written_entities,e_used);
859  }
860  }
861 }

References EFFECT, effect_any_reference, effect_write_p, FOREACH, load_proper_rw_effects_list(), reference_variable, set_add_element(), and store_effect_p().

Referenced by copy_to_statement(), and transfert_statement().

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

◆ ikernel_load_store()

bool ikernel_load_store ( __attribute__((unused)) char *  module_name)

set_entity_to_size(); should be performed at the workspace level

out regions

in regions

preconditions

Definition at line 1301 of file ikernels.c.

1301  {
1302  statement module_stat;
1303 
1305  module_name,
1306  true));
1307  module_stat = get_current_module_statement();
1309  /* set_entity_to_size(); should be performed at the workspace level */
1310 
1311  debug_on("KERNEL_DATA_MAPPING_DEBUG_LEVEL");
1312 
1313  string pe = db_get_memory_resource(DBR_PROPER_EFFECTS, module_name, true);
1315 
1316  /* out regions */
1317  string or = db_get_memory_resource(DBR_OUT_REGIONS, module_name, true);
1319 
1320  /* in regions */
1321  string ir = db_get_memory_resource(DBR_IN_REGIONS, module_name, true);
1323 
1324  /* preconditions */
1325  string precond = db_get_memory_resource(DBR_PRECONDITIONS, module_name, true);
1327 
1328  transfert_statement(module_stat, MAKE_SET(), MAKE_SET(), NULL, NULL);
1329 
1330  DB_PUT_MEMORY_RESOURCE(DBR_CODE,
1331  module_name,
1332  module_stat);
1333 
1336  reset_in_effects();
1340 
1341  return true;
1342 }
void reset_out_effects(void)
void reset_proper_rw_effects(void)
void set_proper_rw_effects(statement_effects)
void set_out_effects(statement_effects)
void set_in_effects(statement_effects)
void reset_in_effects(void)
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
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 void transfert_statement(statement st, set already_transfered_to, set already_transfered_from, set array_to_transfer_to_after, set array_to_transfer_from_before)
Definition: ikernels.c:1152
#define debug_on(env)
Definition: misc-local.h:157
entity local_name_to_top_level_entity(const char *n)
This function try to find a top-level entity from a local name.
Definition: entity.c:1450
void reset_precondition_map(void)
void set_precondition_map(statement_mapping)

References db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_on, get_current_module_statement(), local_name_to_top_level_entity(), MAKE_SET, module_name(), reset_current_module_entity(), reset_current_module_statement(), reset_in_effects(), reset_out_effects(), reset_precondition_map(), reset_proper_rw_effects(), set_current_module_entity(), set_current_module_statement(), set_in_effects(), set_out_effects(), set_precondition_map(), set_proper_rw_effects(), and transfert_statement().

+ Here is the call graph for this function:

◆ init_one_statement()

static void init_one_statement ( statement  st)
static

First initialization (normal use)

If the statement has never been seen, allocate new sets:

Definition at line 379 of file ikernels.c.

379  {
380  if(COPY_FROM_IN( st ) == (set)HASH_UNDEFINED_VALUE) {
381  /* First initialization (normal use) */
382  /* If the statement has never been seen, allocate new sets: */
383  hash_put(copies_from_in, (char *)st, (char *)MAKE_SET());
384  hash_put(copies_from_out, (char *)st, (char *)MAKE_SET());
385  hash_put(copies_to_in, (char *)st, (char *)MAKE_SET());
386  hash_put(copies_to_out, (char *)st, (char *)MAKE_SET());
387  }
388 }
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
static hash_table copies_to_in
copy_to_in maps each statement to the "copy to" data that are in-coming the statement
Definition: ikernels.c:180
static hash_table copies_to_out
copy_to_out maps each statement to the "copy to" data that are out-going from the statement
Definition: ikernels.c:195
static hash_table copies_from_out
copy_from_out maps each statement to the "copy from" data that are out-going from the statement
Definition: ikernels.c:165
static hash_table copies_from_in
copy_from_in maps each statement to the "copy from" data that are in-coming the statement
Definition: ikernels.c:150
#define HASH_UNDEFINED_VALUE
value returned by hash_get() when the key is not found; could also be called HASH_KEY_NOT_FOUND,...
Definition: newgen_hash.h:56

References copies_from_in, copies_from_out, copies_to_in, copies_to_out, COPY_FROM_IN, hash_put(), HASH_UNDEFINED_VALUE, and MAKE_SET.

Referenced by kernel_data_mapping().

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

◆ interprocedural_mapping()

static set interprocedural_mapping ( string  res,
call  c 
)
static

Translate the interprocedural summary for a function into a set of local corresponding parameters (entity only)

of entity

if there are more actuals than formals, they are skipped.

Definition at line 311 of file ikernels.c.

311  {
313  const char* func_name = entity_local_name(callee);
315  func_name,
316  true);
317  set summary = MAKE_SET();
318  set_assign(summary,memory_mapping_map(mem_map));
319 
320 
321  list /* of entity */l_formals = module_formal_parameters(callee);
322  int arg_num, n_formals = gen_length(l_formals);
323  gen_free_list(l_formals);
324 
325  /* if there are more actuals than formals, they are skipped.
326  */
327  set at_call_site = MAKE_SET();
328  list real_args = call_arguments(c);
329  for (arg_num = 1; !ENDP(real_args) && arg_num <= n_formals; real_args
330  = CDR(real_args), arg_num++) {
331  entity formal_ent = find_ith_formal_parameter(callee, arg_num);
332  bool found = false;
333  SET_FOREACH(entity, e, summary) {
334  if(same_entity_p(e, formal_ent)) {
335  set_del_element(summary,summary,e);
336  found = true;
337  break;
338  }
339  }
340  if(found) {
341  expression real_exp = EXPRESSION(CAR(real_args));
342 
343  if(expression_reference_p(real_exp)) {
345  set_add_element(at_call_site, at_call_site, reference_variable(r));
346  } else {
348  "Interprocedural mapping on %s map on a non ref expression ",
349  entity_name(formal_ent));
350  print_syntax(expression_syntax(real_exp));
351  fprintf(stderr, "\n");
352  }
353  }
354  }
355  SET_FOREACH(entity, e, summary) {
356  pips_debug(4,"%s not mapped on formal\n",entity_name(e));
357  if(top_level_entity_p(e)) {
358  set_add_element(at_call_site,at_call_site,e);
359  } else {
360  pips_internal_error("Interprocedural error : entity %s is not a formal"
361  " not a global variable !\n",entity_name(e));
362  }
363  }
364  return at_call_site;
365 }
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
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
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
struct _newgen_struct_memory_mapping_ * memory_mapping
#define memory_mapping_map(x)
void print_syntax(syntax s)
Definition: expression.c:121
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
bool top_level_entity_p(entity e)
Check if the scope of entity e is global.
Definition: entity.c:1130
entity find_ith_formal_parameter(entity the_fnct, int rank)
This function gives back the ith formal parameter, which is found in the declarations of a call or a ...
Definition: entity.c:1863
list module_formal_parameters(entity func)
list module_formal_parameters(entity func) input : an entity representing a function.
Definition: module.c:327
#define syntax_reference(x)
Definition: ri.h:2730
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define call_arguments(x)
Definition: ri.h:711
#define expression_syntax(x)
Definition: ri.h:1247

References call_arguments, call_function, callee, CAR, CDR, db_get_memory_resource(), ENDP, entity_local_name(), entity_name, EXPRESSION, expression_reference_p(), expression_syntax, find_ith_formal_parameter(), fprintf(), gen_free_list(), gen_length(), MAKE_SET, memory_mapping_map, module_formal_parameters(), pips_debug, pips_internal_error, pips_user_warning, print_syntax(), reference_variable, same_entity_p(), set_add_element(), set_assign(), set_del_element(), SET_FOREACH, syntax_reference, and top_level_entity_p().

Referenced by copy_from_call(), and copy_to_call().

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

◆ is_a_kernel()

bool is_a_kernel ( const char *  func_name)
Parameters
func_nameunc_name

Definition at line 369 of file ikernels.c.

369  {
370  callees kernels = (callees)db_get_memory_resource(DBR_KERNELS, "", true);
371  bool found = false;
372  FOREACH(STRING,kernel_name,callees_callees(kernels)) {
373  if((found = (same_string_p(kernel_name,func_name))))
374  break;
375  }
376  return found;
377 }
#define STRING(x)
Definition: genC.h:87
#define same_string_p(s1, s2)
struct _newgen_struct_callees_ * callees
Definition: ri.h:55
#define callees_callees(x)
Definition: ri.h:675

References callees_callees, db_get_memory_resource(), FOREACH, same_string_p, and STRING.

Referenced by copy_from_call(), copy_to_call(), kernel_data_mapping(), and opencl_compile_mergeable_dag().

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

◆ kernel_data_mapping()

bool kernel_data_mapping ( char *  module_name)

set_entity_to_size(); should be performed at the workspace level

regions

out regions

in regions

preconditions

preconditions

Initialize global hashtables

Initialize set for each statement

Run the pass except if current module is a kernel

Parameters
module_nameodule_name

Definition at line 1344 of file ikernels.c.

1344  {
1345  statement module_stat;
1346 
1348  module_name,
1349  true));
1350  module_stat = get_current_module_statement();
1352  /* set_entity_to_size(); should be performed at the workspace level */
1353 
1354  debug_on("KERNEL_DATA_MAPPING_DEBUG_LEVEL");
1355 
1356 
1357  /* regions */
1358  string region = db_get_memory_resource(DBR_REGIONS, module_name, true);
1360 
1361 
1362  /* out regions */
1363  string or = db_get_memory_resource(DBR_OUT_REGIONS, module_name, true);
1365 
1366  /* in regions */
1367  string ir = db_get_memory_resource(DBR_IN_REGIONS, module_name, true);
1369 
1370  /* preconditions */
1371  string precond = db_get_memory_resource(DBR_PRECONDITIONS, module_name, true);
1373 
1374  /* preconditions */
1375  string cumu = db_get_memory_resource(DBR_CUMULATED_EFFECTS, module_name, true);
1377 
1378  // Stuff for ... ?
1380 
1381 
1382  /* Initialize global hashtables */
1387 
1388  /* Initialize set for each statement */
1390 
1391  /* Run the pass except if current module is a kernel */
1392  if(!is_a_kernel(module_name)) {
1393  copy_from_statement(module_stat);
1394  copy_to_statement(module_stat);
1395  // Is it a bad hack ? Should we need a fix point here ?
1396  copy_from_statement(module_stat);
1397 
1398  transfert_statement(module_stat, MAKE_SET(), MAKE_SET(), MAKE_SET(), MAKE_SET());
1399  }
1400 
1401  ifdebug(1) {
1402  pips_debug(1,"Interprocedural summary for %s :\n To :",module_name);
1403  print_entities(set_to_list(COPY_TO_IN(module_stat)));
1404  fprintf(stderr,"\n From :");
1405  print_entities(set_to_list(COPY_FROM_OUT(module_stat)));
1406  fprintf(stderr,"\n");
1407  }
1408 
1409  DB_PUT_MEMORY_RESOURCE(DBR_CODE,
1410  module_name,
1411  module_stat);
1412 
1413  DB_PUT_MEMORY_RESOURCE(DBR_KERNEL_COPY_IN,
1414  module_name,
1415  make_memory_mapping(COPY_TO_IN(module_stat)));
1416  DB_PUT_MEMORY_RESOURCE(DBR_KERNEL_COPY_OUT,
1417  module_name,
1418  make_memory_mapping(COPY_FROM_OUT(module_stat)));
1419 
1420 #define TABLE_FREE(t) \
1421  {HASH_MAP( k, v, {set_free( (set)v ) ;}, t ) ; hash_table_free(t);}
1422 
1423  // TABLE_FREE(copies_from_in);
1424  // TABLE_FREE(copies_from_out);
1425 
1428  reset_in_effects();
1434 
1435  return true;
1436 }
memory_mapping make_memory_mapping(set a)
#define region
simulation of the type region
void set_cumulated_rw_effects(statement_effects)
void reset_cumulated_rw_effects(void)
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
#define INIT_STATEMENT_SIZE
Definition: ikernels.c:141
static void init_one_statement(statement st)
Definition: ikernels.c:379
@ hash_pointer
Definition: newgen_hash.h:32
void module_to_value_mappings(entity m)
void module_to_value_mappings(entity m): build hash tables between variables and values (old,...
Definition: mappings.c:624
void free_value_mappings(void)
Normal call to free the mappings.
Definition: value.c:1212

References copies_from_in, copies_from_out, copies_to_in, copies_to_out, COPY_FROM_OUT, copy_from_statement(), COPY_TO_IN, copy_to_statement(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_on, fprintf(), free_value_mappings(), gen_recurse, gen_true(), get_current_module_entity(), get_current_module_statement(), hash_pointer, hash_table_make(), ifdebug, init_one_statement(), INIT_STATEMENT_SIZE, is_a_kernel(), local_name_to_top_level_entity(), make_memory_mapping(), MAKE_SET, module_name(), module_to_value_mappings(), pips_debug, print_entities(), region, reset_cumulated_rw_effects(), reset_current_module_entity(), reset_current_module_statement(), reset_in_effects(), reset_out_effects(), reset_precondition_map(), reset_proper_rw_effects(), set_cumulated_rw_effects(), set_current_module_entity(), set_current_module_statement(), set_in_effects(), set_out_effects(), set_precondition_map(), set_proper_rw_effects(), set_to_list(), statement_domain, and transfert_statement().

+ Here is the call graph for this function:

◆ make_dma_transfert()

static statement make_dma_transfert ( entity  e,
enum region_to_dma_switch  dma 
)
static

Definition at line 110 of file ikernels.c.

110  {
111 
112  const char* function_name = get_dma_name(dma, 0);
113  entity mcpy = module_name_to_entity(function_name);
114  if(entity_undefined_p(mcpy)) {
115  mcpy
116  = make_empty_subroutine(function_name,
118  pips_user_warning("Cannot find \"%s\" method. Are you sure you have set\n"
119  "KERNEL_LOAD_STORE_..._FUNCTION "
120  "to a defined entity and added the correct .c file?\n",function_name);
121  } else {
123  }
124  list args = NIL;
125  /*
126  expression entity_exp = entity_to_expression(e);
127  if(entity_pointer_p(e)) {
128  entity_exp = MakeUnaryCall(entity_intrinsic(DEREFERENCING_OPERATOR_NAME),
129  entity_to_expression(e));
130  }
131 
132  expression size_of_e = MakeSizeofExpression(entity_exp);*/
134 
135  args = make_expression_list(entity_to_expression(e),size_of_e);
136 
137  call c = make_call(mcpy, args);
139 }
call make_call(entity a1, list a2)
Definition: ri.c:269
language copy_language(language p)
LANGUAGE.
Definition: ri.c:1202
instruction make_instruction_call(call _field_)
Definition: ri.c:1184
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
Definition: statement.c:597
static const char * get_dma_name(enum region_to_dma_switch m, int d)
converts a region_to_dma_switch to corresponding dma name according to properties
Definition: ikernels.c:92
static expression makeTransfertSizeExpression(entity e)
Make a sizeof expression.
Definition: ikernels.c:63
#define make_expression_list(stats...)
#define module_language(e)
implemented as a macro to allow lhs
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
entity make_empty_subroutine(const char *name, language l)
Definition: entity.c:268
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
#define entity_undefined_p(x)
Definition: ri.h:2762
void AddEntityToModuleCompilationUnit(entity e, entity module)
Definition: module.c:301

References AddEntityToModuleCompilationUnit(), copy_language(), entity_to_expression(), entity_undefined_p, get_current_module_entity(), get_dma_name(), instruction_to_statement(), make_call(), make_empty_subroutine(), make_expression_list, make_instruction_call(), makeTransfertSizeExpression(), module_language, module_name_to_entity(), NIL, and pips_user_warning.

Referenced by transfert_block(), and transfert_loop().

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

◆ makeTransfertSizeExpression()

static expression makeTransfertSizeExpression ( entity  e)
static

Make a sizeof expression.

Definition at line 63 of file ikernels.c.

63  {
64  type array_type = entity_type(e);
65  pips_assert("Must be a variable type", type_variable_p(array_type));
66  variable v_type = type_variable(array_type);
67 
68 
69  // FIXME free memory
70  type element_type = make_type_variable(
72  copy_basic(variable_basic(v_type)),
73  NIL,NIL)
74  );
75 
76  expression transfer_size = SizeOfDimensions(variable_dimensions(v_type));
77  transfer_size=MakeBinaryCall(
82  ),
83  transfer_size);
84 
85  return transfer_size;
86 }
expression make_expression(syntax a1, normalized a2)
Definition: ri.c:886
type make_type_variable(variable _field_)
Definition: ri.c:2715
syntax make_syntax_sizeofexpression(sizeofexpression _field_)
Definition: ri.c:2506
basic copy_basic(basic p)
BASIC.
Definition: ri.c:104
sizeofexpression make_sizeofexpression_type(type _field_)
Definition: ri.c:2177
variable make_variable(basic a1, list a2, list a3)
Definition: ri.c:2895
#define MULTIPLY_OPERATOR_NAME
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
expression SizeOfDimensions(list)
computes the product of all dimensions in dims
Definition: size.c:522
#define variable_basic(x)
Definition: ri.h:3120

References copy_basic(), entity_intrinsic(), entity_type, make_expression(), make_sizeofexpression_type(), make_syntax_sizeofexpression(), make_type_variable(), make_variable(), MakeBinaryCall(), MULTIPLY_OPERATOR_NAME, NIL, normalized_undefined, pips_assert, SizeOfDimensions(), type_variable, type_variable_p, variable_basic, and variable_dimensions.

Referenced by make_dma_transfert(), and wrap_argument().

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

◆ transfert_block()

static void transfert_block ( _UNUSED_ statement  st,
list  sts,
set  already_transfered,
set  already_transfered_from 
)
static

loop over statements inside the block

Compute the transfer for this statement

Definition at line 975 of file ikernels.c.

978  {
979 
980  pips_debug(4,"Entering transfert_block\n");
981 
982  /* loop over statements inside the block */
983  for (list current = (sts); !ENDP(current); POP(current)) {
984  statement one = STATEMENT(CAR(current));
985 
986  // These are here to record what a statement require to transfer
987  // We generate transfers only in sequence
988  set transfert_to = MAKE_SET();
989  set transfert_from = MAKE_SET();
990 
991  /* Compute the transfer for this statement */
993  already_transfered,
994  already_transfered_from,
995  transfert_to,
996  transfert_from);
997  // Really insert the transfers statement
998  list t_from = set_to_sorted_list(transfert_from,(gen_cmp_func_t)compare_entities);
999  FOREACH(entity, e_from, t_from) {
1000  statement new_st_from = make_dma_transfert(e_from, dma_store);
1001  CDR(current) = CONS(statement,one,CDR(current));
1002  CAR(current).e = new_st_from;
1003  POP(current);
1004  }
1005  gen_free_list(t_from);
1006 
1007 
1009  FOREACH(entity, e_to, t_to) {
1010  statement new_st_to = make_dma_transfert(e_to, dma_load);
1011  CDR(current) = CONS(statement,new_st_to,CDR(current));
1012  POP(current);
1013  }
1014  gen_free_list(t_to);
1015  }
1016 
1017 
1018 }
@ dma_store
@ dma_load
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
static statement make_dma_transfert(entity e, enum region_to_dma_switch dma)
Definition: ikernels.c:110
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
static size_t current
Definition: string.c:115

References CAR, CDR, compare_entities(), CONS, current, dma_load, dma_store, ENDP, FOREACH, gen_free_list(), make_dma_transfert(), MAKE_SET, pips_debug, POP, set_to_sorted_list(), STATEMENT, and transfert_statement().

Referenced by transfert_statement().

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

◆ transfert_call()

static void transfert_call ( _UNUSED_ statement  st,
_UNUSED_ call  c,
_UNUSED_ set  already_transfered,
_UNUSED_ set  already_transfered_from 
)
static

Definition at line 1138 of file ikernels.c.

1141  {
1142 }

Referenced by transfert_statement().

+ Here is the caller graph for this function:

◆ transfert_forloop()

static void transfert_forloop ( _UNUSED_ statement  st,
forloop  l,
set  already_transfered,
set  already_transfered_from,
set  transfert_to,
set  transfert_from 
)
static

Compute loop body

Definition at line 1123 of file ikernels.c.

1128  {
1129  statement body = forloop_body(l);
1130 
1131  /* Compute loop body */
1132  transfert_statement(body,
1133  already_transfered,
1134  already_transfered_from,
1135  transfert_to,
1136  transfert_from);
1137 }

References forloop_body, and transfert_statement().

Referenced by transfert_statement().

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

◆ transfert_loop()

static void transfert_loop ( _UNUSED_ statement  st,
loop  l,
set  already_transfered,
set  already_transfered_from,
set  transfert_to,
set  transfert_from 
)
static

Compute loop body

Definition at line 1059 of file ikernels.c.

1064  {
1065  statement body = loop_body(l);
1066 
1067  /* Compute loop body */
1068  transfert_statement(body,
1069  already_transfered,
1070  already_transfered_from,
1071  transfert_to,
1072  transfert_from);
1073 
1074 
1075  /*
1076  * At the end of a loop, we check that any transfer that need to be done
1077  */
1078 
1079  // Retrieve the last statement of the loop body
1080  set last_copy_from = set_undefined;
1081  if (!statement_sequence_p(body)) {
1082  last_copy_from = COPY_FROM_OUT(body);
1083  } else {
1084  // FC: apparently last_copy_from may not be always assigned...
1086  set copy_from = COPY_FROM_OUT(s);
1087  if (copy_from && !set_undefined_p(copy_from))
1088  last_copy_from = copy_from;
1089  }
1090  }
1091 
1092  /*
1093  * Compute the set of entity that are not on the GPU at the begin of the loop
1094  * but need a copy-out at the end, after the last statement
1095  */
1096  set fixed_transfert_from = MAKE_SET();
1097  set_difference(fixed_transfert_from,last_copy_from,COPY_FROM_OUT(body));
1098  list t_from = set_to_sorted_list(fixed_transfert_from,(gen_cmp_func_t)compare_entities);
1099  set_free(fixed_transfert_from);
1100  // Insert transfers at the end of the loop !
1101  FOREACH(entity, e_from, t_from) {
1102  insert_statement(body,make_dma_transfert(e_from, dma_store),false);
1103  }
1104 
1105 
1106 }
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
void insert_statement(statement, statement, bool)
This is the normal entry point.
Definition: statement.c:2570
#define set_undefined
Definition: newgen_set.h:48
#define set_undefined_p(s)
Definition: newgen_set.h:49
#define sequence_statements(x)
Definition: ri.h:2360

References compare_entities(), COPY_FROM_OUT, dma_store, FOREACH, insert_statement(), loop_body, make_dma_transfert(), MAKE_SET, sequence_statements, set_difference(), set_free(), set_to_sorted_list(), set_undefined, set_undefined_p, statement_sequence(), statement_sequence_p(), and transfert_statement().

Referenced by transfert_statement().

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

◆ transfert_statement()

static void transfert_statement ( statement  st,
set  already_transfered_to,
set  already_transfered_from,
set  array_to_transfer_to_after,
set  array_to_transfer_from_before 
)
static

Compute "copy from" sets for the instruction : recursion

The second argument is not used

Definition at line 1152 of file ikernels.c.

1156  {
1157 
1159 
1160  set transferts_to = MAKE_SET();
1161  set_difference(transferts_to, COPY_TO_OUT(st), COPY_TO_IN(st));
1162  set_difference(transferts_to, transferts_to, COPY_FROM_OUT(st));
1163  set_difference(transferts_to, transferts_to, already_transfered_to);
1164 
1165  // We remove from "transfers_to" what is not written by this statement
1166  set allowed_to_transfer_to= MAKE_SET();
1167  gen_context_recurse(st, allowed_to_transfer_to,
1169  ifdebug(4) {
1170  pips_debug(4,"Removing from transfer_to what is not written here : ");
1171  set removed = MAKE_SET();
1172  set_difference(removed,transferts_to,allowed_to_transfer_to);
1174  FOREACH(entity, e, t_to) {
1175  fprintf(stderr, "%s ", entity_name(e));
1176  }
1177  fprintf(stderr, "\n");
1178  }
1179  set_intersection(transferts_to,transferts_to,allowed_to_transfer_to);
1180  set_free(allowed_to_transfer_to);
1181 
1182 
1183  SET_FOREACH(entity, e, transferts_to) {
1184  set_add_element(already_transfered_to, already_transfered_to, e);
1185  set_add_element(array_to_transfer_to_after, array_to_transfer_to_after, e);
1186 
1187  ifdebug(2) {
1188  string str = strdup(concatenate("Transfert to accel : ",
1189  entity_local_name(e),
1190  "\n",
1191  NULL));
1192  pips_debug(4,"(%zd) %s",statement_number(st),concatenate("Inserting :",str,"\n",NULL));
1194  free(str);
1195  }
1196  }
1197 
1198  set transferts_from = MAKE_SET();
1199  set_difference(transferts_from, COPY_FROM_IN(st), COPY_FROM_OUT(st));
1200  set_difference(transferts_from, transferts_from, COPY_TO_IN(st));
1201  set_difference(transferts_from, transferts_from, already_transfered_from);
1202 
1203  {
1204  SET_FOREACH(entity, e, transferts_from)
1205  {
1206  set_add_element(already_transfered_from, already_transfered_from, e);
1207  set_add_element(array_to_transfer_from_before,
1208  array_to_transfer_from_before,
1209  e);
1210  ifdebug(2) {
1211  string str = strdup(concatenate("Transfert from accel : ",
1212  entity_local_name(e),
1213  "\n",
1214  NULL));
1215  pips_debug(4,"Inserting : %s\n",str);
1217  free(str);
1218  }
1219  }
1220  }
1221 
1222  /* Compute "copy from" sets for the instruction : recursion */
1223  switch(instruction_tag(i)) {
1224  case is_instruction_block:
1225  transfert_block(st,
1226  instruction_block( i ),
1227  already_transfered_to,
1228  already_transfered_from);
1229  break;
1230  case is_instruction_test:
1231  transfert_test(st,
1232  instruction_test( i ),
1233  already_transfered_to,
1234  already_transfered_from,
1235  array_to_transfer_to_after,
1236  array_to_transfer_from_before);
1237  break;
1238  case is_instruction_loop:
1239  transfert_loop(st,
1240  instruction_loop( i ),
1241  already_transfered_to,
1242  already_transfered_from,
1243  array_to_transfer_to_after,
1244  array_to_transfer_from_before);
1245  break;
1248  instruction_whileloop( i ),
1249  already_transfered_to,
1250  already_transfered_from,
1251  array_to_transfer_to_after,
1252  array_to_transfer_from_before);
1253  break;
1255  transfert_forloop(st,
1256  instruction_forloop( i ),
1257  already_transfered_to,
1258  already_transfered_from,
1259  array_to_transfer_to_after,
1260  array_to_transfer_from_before);
1261  break;
1262  case is_instruction_call:
1263  transfert_call(st,
1264  instruction_call( i ),
1265  already_transfered_to,
1266  already_transfered_from);
1267  break;
1269  /* The second argument is not used */
1270  transfert_call(st,
1272  already_transfered_to,
1273  already_transfered_from);
1274  break;
1275  case is_instruction_goto:
1276  pips_internal_error("Unexpected instruction tag %d: GOTO\n", i);
1277  break;
1281  already_transfered_to,
1282  already_transfered_from);
1283  break;
1284  default:
1285  pips_internal_error("Unknown tag %d\n", instruction_tag(i) );
1286  }
1287 
1288 
1289 
1290  set killed_transfer = MAKE_SET();
1291  set_difference(killed_transfer, COPY_TO_OUT(st), COPY_TO_IN(st));
1292  set_difference(already_transfered_to, already_transfered_to, killed_transfer);
1293  set_difference(killed_transfer, COPY_FROM_IN(st), COPY_FROM_OUT(st));
1294  set_difference(already_transfered_from,
1295  already_transfered_from,
1296  killed_transfer);
1297  set_free(killed_transfer);
1298 
1299 }
static void transfert_call(_UNUSED_ statement st, _UNUSED_ call c, _UNUSED_ set already_transfered, _UNUSED_ set already_transfered_from)
Definition: ikernels.c:1138
static void transfert_block(_UNUSED_ statement st, list sts, set already_transfered, set already_transfered_from)
Definition: ikernels.c:975
static void transfert_forloop(_UNUSED_ statement st, forloop l, set already_transfered, set already_transfered_from, set transfert_to, set transfert_from)
Definition: ikernels.c:1123
static void transfert_test(_UNUSED_ statement st, test t, set already_transfered, set already_transfered_from, set transfert_to, set transfert_from)
Definition: ikernels.c:1019
static void transfert_whileloop(_UNUSED_ statement st, whileloop l, set already_transfered, set already_transfered_from, set transfert_to, set transfert_from)
Definition: ikernels.c:1108
static void transfert_unstructured(_UNUSED_ statement st, _UNUSED_ unstructured u, _UNUSED_ set already_transfered, _UNUSED_ set already_transfered_from)
Definition: ikernels.c:1144
static void transfert_loop(_UNUSED_ statement st, loop l, set already_transfered, set already_transfered_from, set transfert_to, set transfert_from)
Definition: ikernels.c:1059
#define statement_number(x)
Definition: ri.h:2452

References compare_entities(), concatenate(), COPY_FROM_IN, COPY_FROM_OUT, COPY_TO_IN, COPY_TO_OUT, entity_local_name(), entity_name, FOREACH, fprintf(), free(), gen_context_recurse, gen_true2(), get_written_entities(), ifdebug, insert_comments_to_statement(), instruction_block, instruction_call, instruction_expression, instruction_forloop, instruction_loop, instruction_tag, instruction_test, instruction_unstructured, instruction_whileloop, is_instruction_block, is_instruction_call, is_instruction_expression, is_instruction_forloop, is_instruction_goto, is_instruction_loop, is_instruction_test, is_instruction_unstructured, is_instruction_whileloop, MAKE_SET, pips_debug, pips_internal_error, set_add_element(), set_difference(), SET_FOREACH, set_free(), set_intersection(), set_to_sorted_list(), statement_domain, statement_instruction, statement_number, strdup(), transfert_block(), transfert_call(), transfert_forloop(), transfert_loop(), transfert_test(), transfert_unstructured(), and transfert_whileloop().

Referenced by ikernel_load_store(), kernel_data_mapping(), transfert_block(), transfert_forloop(), transfert_loop(), transfert_test(), and transfert_whileloop().

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

◆ transfert_test()

static void transfert_test ( _UNUSED_ statement  st,
test  t,
set  already_transfered,
set  already_transfered_from,
set  transfert_to,
set  transfert_from 
)
static

Definition at line 1019 of file ikernels.c.

1024  {
1025  set already_transfered_from_tmp = set_make(set_pointer);
1026  set already_transfered_tmp = set_make(set_pointer);
1027  set transfert_to_tmp = set_make(set_pointer);
1028  set transfert_from_tmp = set_make(set_pointer);
1029 
1030  set_assign(already_transfered_from_tmp,already_transfered_from);
1031  set_assign(already_transfered_tmp,already_transfered);
1032  set_assign(transfert_to_tmp,transfert_to);
1033  set_assign(transfert_from_tmp,transfert_from);
1034 
1035 
1037  already_transfered_tmp,
1038  already_transfered_from_tmp,
1039  transfert_to_tmp,
1040  transfert_from_tmp);
1041 
1042 
1043  set_assign(already_transfered_from_tmp,already_transfered_from);
1044  set_assign(already_transfered_tmp,already_transfered);
1045  set_assign(transfert_to_tmp,transfert_to);
1046  set_assign(transfert_from_tmp,transfert_from);
1047 
1049  already_transfered_tmp,
1050  already_transfered_from_tmp,
1051  transfert_to_tmp,
1052  transfert_from_tmp);
1053 
1054 
1055 }

References set_assign(), set_make(), set_pointer, test_false, test_true, and transfert_statement().

Referenced by transfert_statement().

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

◆ transfert_unstructured()

static void transfert_unstructured ( _UNUSED_ statement  st,
_UNUSED_ unstructured  u,
_UNUSED_ set  already_transfered,
_UNUSED_ set  already_transfered_from 
)
static

Definition at line 1144 of file ikernels.c.

1147  {
1148  //pips_user_warning("Unimplemented !! Results may be wrong...\n");
1149  pips_user_error("Unstructured are not processed. Please structure your input code.\n");
1150 }

References pips_user_error.

Referenced by transfert_statement().

+ Here is the caller graph for this function:

◆ transfert_whileloop()

static void transfert_whileloop ( _UNUSED_ statement  st,
whileloop  l,
set  already_transfered,
set  already_transfered_from,
set  transfert_to,
set  transfert_from 
)
static

Compute loop body

Definition at line 1108 of file ikernels.c.

1113  {
1114  statement body = whileloop_body(l);
1115 
1116  /* Compute loop body */
1117  transfert_statement(body,
1118  already_transfered,
1119  already_transfered_from,
1120  transfert_to,
1121  transfert_from);
1122 }

References transfert_statement(), and whileloop_body.

Referenced by transfert_statement().

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

◆ wrap_argument()

static void wrap_argument ( syntax  s)
static

ize_of_e

Definition at line 1445 of file ikernels.c.

1445  {
1446  if(syntax_reference_p(s)
1449 
1450 
1451 /*
1452  sizeofexpression size_of = make_sizeofexpression_expression(transfer_size);
1453  expression size_of_e;
1454  size_of_e = make_expression(make_syntax_sizeofexpression(size_of),
1455  normalized_undefined);
1456 */
1457  syntax new_ref = copy_syntax(s);
1459  list args = make_expression_list(make_expression(new_ref,
1461  makeTransfertSizeExpression(e)/*size_of_e*/);
1463 
1465  }
1466 
1467 }
syntax copy_syntax(syntax p)
SYNTAX.
Definition: ri.c:2442
static entity wrapper_function
Definition: ikernels.c:1442
#define syntax_reference_p(x)
Definition: ri.h:2728
#define syntax_tag(x)
Definition: ri.h:2727
@ is_syntax_call
Definition: ri.h:2693
#define syntax_call(x)
Definition: ri.h:2736

References AddEntityToModuleCompilationUnit(), copy_syntax(), entity_array_p(), get_current_module_entity(), is_syntax_call, make_call(), make_expression(), make_expression_list, makeTransfertSizeExpression(), normalized_undefined, reference_variable, syntax_call, syntax_reference, syntax_reference_p, syntax_tag, and wrapper_function.

Referenced by wrap_call_argument().

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

◆ wrap_call_argument()

static void wrap_call_argument ( call  c,
const char *  module_name 
)
static

Definition at line 1469 of file ikernels.c.

1469  {
1470  if(!call_intrinsic_p(c)
1472 
1473  list args = call_arguments(c);
1474  for (expression e; !ENDP(args); POP(args)) {
1475  e = EXPRESSION(CAR(args));
1477  }
1478 
1479  }
1480 }
static void wrap_argument(syntax s)
Definition: ikernels.c:1445
#define call_intrinsic_p(C)
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
#define syntax_domain
newgen_synchronization_domain_defined
Definition: ri.h:402

References call_arguments, call_function, call_intrinsic_p, CAR, ENDP, EXPRESSION, gen_recurse, gen_true(), module_local_name(), module_name(), POP, same_string_p, syntax_domain, and wrap_argument().

Referenced by wrap_kernel_argument().

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

◆ wrap_kernel_argument()

bool wrap_kernel_argument ( char *  module_name)

This pass will wrap kernel arguments in a call to a wrapper function.

prelude

o the job

validate

ostlude

Parameters
module_nameodule_name

Definition at line 1486 of file ikernels.c.

1486  {
1487 
1489 
1490  debug_on("WRAP_KERNEL_ARGUMENT_DEBUG_LEVEL");
1491 
1492  callees callers = (callees)db_get_memory_resource(DBR_CALLERS,
1493  module_name,
1494  true);
1495 
1496  // Get the wrapper function
1497  const char* function_name = get_string_property("WRAP_KERNEL_ARGUMENT_FUNCTION_NAME");
1498  wrapper_function = module_name_to_entity(function_name);
1501  = make_empty_subroutine(function_name,
1502  copy_language(module_language(kernel_entity)));
1503  pips_user_warning("Cannot find \"%s\" method. Are you sure you have set\n"
1504  "WRAP_KERNEL_ARGUMENT_FUNCTION_NAME"
1505  "to a defined entity and added the correct .c file?\n",function_name);
1506  }
1507 
1508 
1509 
1510 
1512  /* prelude */
1515  caller_name,
1516  true));
1517 
1518  /*do the job */
1521  /* validate */
1525 
1526  /*postlude*/
1529  }
1530 
1531  return true;
1532 }
static const char * caller_name
Definition: alias_check.c:122
callees compute_callees(const statement stat)
Recompute the callees of a module statement.
Definition: callgraph.c:355
static void wrap_call_argument(call c, const char *module_name)
Definition: ikernels.c:1469
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58

References call_domain, callees_callees, caller_name, compute_callees(), copy_language(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_on, entity_undefined_p, FOREACH, gen_context_recurse, gen_true2(), get_current_module_statement(), get_string_property(), local_name_to_top_level_entity(), make_empty_subroutine(), module_language, module_name(), module_name_to_entity(), module_reorder(), pips_user_warning, reset_current_module_entity(), reset_current_module_statement(), set_current_module_entity(), set_current_module_statement(), STRING, wrap_call_argument(), and wrapper_function.

+ Here is the call graph for this function:

Variable Documentation

◆ copies_from_in

hash_table copies_from_in
static

copy_from_in maps each statement to the "copy from" data that are in-coming the statement

Definition at line 150 of file ikernels.c.

Referenced by init_one_statement(), and kernel_data_mapping().

◆ copies_from_out

hash_table copies_from_out
static

copy_from_out maps each statement to the "copy from" data that are out-going from the statement

Definition at line 165 of file ikernels.c.

Referenced by init_one_statement(), and kernel_data_mapping().

◆ copies_to_in

hash_table copies_to_in
static

copy_to_in maps each statement to the "copy to" data that are in-coming the statement

Definition at line 180 of file ikernels.c.

Referenced by init_one_statement(), and kernel_data_mapping().

◆ copies_to_out

hash_table copies_to_out
static

copy_to_out maps each statement to the "copy to" data that are out-going from the statement

Definition at line 195 of file ikernels.c.

Referenced by init_one_statement(), and kernel_data_mapping().

◆ wrapper_function

entity wrapper_function = NULL
static

Definition at line 1442 of file ikernels.c.

Referenced by wrap_argument(), and wrap_kernel_argument().