PIPS
freia.c File Reference
#include <stdint.h>
#include <stdlib.h>
#include "genC.h"
#include "misc.h"
#include "freia.h"
#include "linear.h"
#include "pipsdbm.h"
#include "ri.h"
#include "effects.h"
#include "ri-util.h"
#include "prettyprint.h"
#include "effects-util.h"
#include "properties.h"
#include "c_syntax.h"
#include "freia_spoc_private.h"
#include "hwac.h"
#include "effects-generic.h"
+ Include dependency graph for freia.c:

Go to the source code of this file.

Data Structures

struct  fcs_ctx
 
struct  fis_ctx
 
struct  freia_info
 

Functions

static bool fcs_call_flt (call c, fcs_ctx *ctx)
 
static void freia_cleanup_status (statement s, set helpers)
 
static bool fis_call_flt (call c, fis_ctx *ctx)
 
static bool freia_image_shuffle (statement s, set shuffled)
 
static void sctc_call_rwt (call c, int *count)
 
static void switch_cast_to_copy (statement s)
 switch all image casts to image copies in "s" More...
 
static bool freia_stmt_free_p (const statement s)
 
static bool freia_alloc_call_p (const call c)
 
static bool freia_alloc_stat_p (const statement s)
 
static void move_ahead (list ls, statement target, sequence sq)
 move statements in l ahead of s in sq note that ls is in reverse order... More...
 
static int freia_cmp_statement (const statement *s1, const statement *s2)
 order two statements for qsort. More...
 
static string stmt_nb (void *s)
 debug helper More...
 
static list clean_list_head (list ls)
 remove non aipo statements at the head of ls More...
 
static list clean_statement_list_for_aipo (list ls)
 remove unrelated stuff at head & tail, so that it does not come in later on and possibly trouble the compilation. More...
 
static void sort_subsequence (list ls, sequence sq)
 reorder a little bit statements, so that allocs & deallocs are up front or in the back, and may be removed by the previous function. More...
 
bool freia_some_effects_on_images (statement s)
 tell whether a statement has no effects on images. More...
 
static void update_written_variables (set written, statement s)
 update the set of written variables, as seen from effects, with a statement this is really to rebuild a poor's man dependency graph in order to move some statements around... More...
 
static bool statement_depends_p (set written, statement s)
 
static bool fsi_loop_flt (__attribute__((unused)) gen_chunk *o, freia_info *fsip)
 
static void fsi_loop_rwt (__attribute__((unused)) gen_chunk *o, freia_info *fsip)
 
expression freia_transpose_kernel (const expression se)
 Transpose a structuring element expression. More...
 
bool freia_is_transpose_call (statement s)
 Detect a call to a se transposition function and transpose the arguments. More...
 
static bool fsi_stmt_flt (statement s, freia_info *fsip)
 detect one lone aipo statement out of a sequence... More...
 
static bool fsi_seq_flt (sequence sq, freia_info *fsip)
 consider a sequence More...
 
static _int min_statement (list ls)
 
static int fsi_cmp (const list *l1, const list *l2)
 
static void fsi_sort (list lls)
 
static void collect_images (reference r, set referenced)
 
static bool freia_cleanup_sequence_rec (statement modstat, set referenced)
 
static bool freia_cleanup_main_sequence (statement modstat)
 
string freia_compile (string module, statement mod_stat, string target)
 freia_compile: compile freia module & statement for target More...
 

Variables

static hash_table fsi_number = NULL
 

Function Documentation

◆ clean_list_head()

static list clean_list_head ( list  ls)
static

remove non aipo statements at the head of ls

Returns
updated list

Definition at line 330 of file freia.c.

331 {
332  list head = ls, prev = NIL;
333  while (ls && !freia_statement_aipo_call_p(STATEMENT(CAR(ls))))
334  prev = ls, ls = CDR(ls);
335  if (prev) CDR(prev) = NIL, gen_free_list(head);
336  return ls;
337 }
bool freia_statement_aipo_call_p(const statement s)
returns whether the statement is a FREIA call.
Definition: freia-utils.c:814
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
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
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References CAR, CDR, freia_statement_aipo_call_p(), gen_free_list(), NIL, and STATEMENT.

Referenced by clean_statement_list_for_aipo().

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

◆ clean_statement_list_for_aipo()

static list clean_statement_list_for_aipo ( list  ls)
static

remove unrelated stuff at head & tail, so that it does not come in later on and possibly trouble the compilation.

Returns
updated list

Definition at line 343 of file freia.c.

344 {
346 }
static list clean_list_head(list ls)
remove non aipo statements at the head of ls
Definition: freia.c:330
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304

References clean_list_head(), and gen_nreverse().

Referenced by fsi_seq_flt().

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

◆ collect_images()

static void collect_images ( reference  r,
set  referenced 
)
static

Definition at line 705 of file freia.c.

706 {
707  entity var = reference_variable(r);
710 }
bool freia_image_variable_p(const entity var)
rather approximative?
Definition: freia-utils.c:768
bool set_belong_p(const set, const void *)
Definition: set.c:194
set set_add_element(set, const set, const void *)
Definition: set.c:152
static list referenced
returns the list of referenced variables
Definition: utils.c:60
#define reference_variable(x)
Definition: ri.h:2326

References freia_image_variable_p(), reference_variable, referenced, set_add_element(), and set_belong_p().

Referenced by freia_cleanup_sequence_rec().

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

◆ fcs_call_flt()

static bool fcs_call_flt ( call  c,
fcs_ctx ctx 
)
static

Definition at line 60 of file freia.c.

61 {
62  entity called = call_function(c);
63  if (freia_assignment_p(called))
64  {
65  list largs = call_arguments(c);
66  pips_assert("two arguments to = or |=", gen_length(largs)==2);
67  expression erhs = EXPRESSION(CAR(CDR(largs)));
68 
69  // catch and eat-up "foo |= 0;"
70  _int val;
71  if (ENTITY_BITWISE_OR_UPDATE_P(called) &&
72  expression_integer_value(erhs, &val) && val==0)
73  {
76  return false;
77  }
78 
79  // else, is it a call to some aipo or helper function?
80  syntax op = expression_syntax(erhs);
81  if (!syntax_call_p(op))
82  return false;
83 
84  // is it an aipo or helper call?
85  call rhs = syntax_call(op);
87  (ctx->helper_functions &&
89  {
90  // record scrapped status variable
91  syntax slhs = expression_syntax(EXPRESSION(CAR(largs)));
92  pips_assert("left hand side is a scalar reference",
93  syntax_reference_p(slhs) &&
97 
98  // and scrap its assignement!
99  call_function(c) = call_function(rhs);
100  call_arguments(c) = call_arguments(rhs);
101 
102  // hmmm... small memory leak in assigned lhs,
103  // but I'm not sure of effect references...
104  call_arguments(rhs) = NIL;
105  free_call(rhs);
106  gen_free_list(largs);
107  }
108  }
109  // no second level anyway? what about ","?
110  return false;
111 }
void free_call(call p)
Definition: ri.c:236
bool entity_freia_api_p(const entity f)
returns whether the entity is a freia API (AIPO) function.
Definition: freia-utils.c:806
bool freia_assignment_p(const entity e)
tell whether it is an assignment to ignore?
Definition: freia-utils.c:703
size_t gen_length(const list l)
Definition: list.c:150
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
intptr_t _int
_INT
Definition: newgen_types.h:53
#define ENTITY_BITWISE_OR_UPDATE_P(e)
#define CONTINUE_FUNCTION_NAME
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
bool expression_integer_value(expression e, intptr_t *pval)
Definition: eval.c:792
#define syntax_reference_p(x)
Definition: ri.h:2728
#define syntax_reference(x)
Definition: ri.h:2730
#define call_function(x)
Definition: ri.h:709
#define syntax_call_p(x)
Definition: ri.h:2734
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define reference_indices(x)
Definition: ri.h:2328
#define syntax_call(x)
Definition: ri.h:2736
#define call_arguments(x)
Definition: ri.h:711
#define expression_syntax(x)
Definition: ri.h:1247
set used_for_status
Definition: freia.c:55
set helper_functions
Definition: freia.c:57

References call_arguments, call_function, CAR, CDR, CONTINUE_FUNCTION_NAME, ENTITY_BITWISE_OR_UPDATE_P, entity_freia_api_p(), entity_intrinsic(), EXPRESSION, expression_integer_value(), expression_syntax, free_call(), freia_assignment_p(), gen_free_list(), gen_length(), fcs_ctx::helper_functions, NIL, pips_assert, reference_indices, reference_variable, set_add_element(), set_belong_p(), syntax_call, syntax_call_p, syntax_reference, syntax_reference_p, and fcs_ctx::used_for_status.

Referenced by freia_cleanup_status().

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

◆ fis_call_flt()

static bool fis_call_flt ( call  c,
fis_ctx ctx 
)
static

Definition at line 148 of file freia.c.

149 {
150  list args = call_arguments(c);
152  {
153  pips_assert("assign takes two args", gen_length(args)==2);
156  if (a2!=entity_undefined &&
158  {
159  set_add_element(ctx->shuffled, ctx->shuffled, a1);
160  set_add_element(ctx->shuffled, ctx->shuffled, a2);
161  return false;
162  }
163  }
164  return true;
165 }
#define ENTITY_ASSIGN_P(e)
entity expression_to_entity(expression e)
just returns the entity of an expression, or entity_undefined
Definition: expression.c:3140
#define entity_undefined
Definition: ri.h:2761
set shuffled
Definition: freia.c:145

References call_arguments, call_function, CAR, CDR, ENTITY_ASSIGN_P, entity_undefined, EXPRESSION, expression_to_entity(), freia_image_variable_p(), gen_length(), pips_assert, set_add_element(), and fis_ctx::shuffled.

Referenced by freia_image_shuffle().

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

◆ freia_alloc_call_p()

static bool freia_alloc_call_p ( const call  c)
static

Definition at line 209 of file freia.c.

210 {
211  entity f = call_function(c);
212  const char *called = entity_user_name(f);
213  return same_string_p(called, FREIA_ALLOC) ||
214  same_string_p(called, FREIA_FREE);
215 }
#define FREIA_FREE
Definition: freia.h:49
#define FREIA_ALLOC
Definition: freia.h:48
#define same_string_p(s1, s2)
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487

References call_function, entity_user_name(), f(), FREIA_ALLOC, FREIA_FREE, and same_string_p.

Referenced by freia_alloc_stat_p().

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

◆ freia_alloc_stat_p()

static bool freia_alloc_stat_p ( const statement  s)
static

Definition at line 217 of file freia.c.

218 {
220  if (c == NULL)
221  return false;
222  entity f = call_function(c);
223  if (ENTITY_CONTINUE_P(f))
224  {
226  {
227  value val = entity_initial(var);
228  if (value_expression_p(val))
229  {
231  if (expression_call_p(eval) &&
233  return false;
234  }
235  else if (!value_unknown_p(val))
236  return false;
237  }
238  return true;
239  }
240  else
241  return freia_alloc_call_p(c);
242 }
call freia_statement_to_call(const statement s)
return the actual function call from a statement, dealing with assign and returns....
Definition: freia-utils.c:973
static bool freia_alloc_call_p(const call c)
Definition: freia.c:209
#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
static Value eval(Pvecteur pv, Value val, Variable var)
#define ENTITY_CONTINUE_P(e)
bool expression_call_p(expression e)
Definition: expression.c:415
call expression_call(expression e)
Definition: expression.c:445
#define value_unknown_p(x)
Definition: ri.h:3077
#define statement_declarations(x)
Definition: ri.h:2460
#define value_expression_p(x)
Definition: ri.h:3080
#define value_expression(x)
Definition: ri.h:3082
#define entity_initial(x)
Definition: ri.h:2796

References call_function, ENTITY_CONTINUE_P, entity_initial, eval(), expression_call(), expression_call_p(), f(), FOREACH, freia_alloc_call_p(), freia_statement_to_call(), statement_declarations, value_expression, value_expression_p, and value_unknown_p.

Referenced by fsi_seq_flt().

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

◆ freia_cleanup_main_sequence()

static bool freia_cleanup_main_sequence ( statement  modstat)
static

Definition at line 768 of file freia.c.

769 {
771  bool changed = freia_cleanup_sequence_rec(modstat, referenced);
773  return changed;
774 }
static bool freia_cleanup_sequence_rec(statement modstat, set referenced)
Definition: freia.c:712
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
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59

References freia_cleanup_sequence_rec(), referenced, set_free(), set_make(), and set_pointer.

Referenced by freia_compile().

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

◆ freia_cleanup_sequence_rec()

static bool freia_cleanup_sequence_rec ( statement  modstat,
set  referenced 
)
static

Definition at line 712 of file freia.c.

713 {
714  //fprintf(stderr, "[freia_cleanup_main_sequence] %p\n", modstat);
715  bool changed = false;
716  instruction i = statement_instruction(modstat);
717 
718  if (instruction_sequence_p(i))
719  {
722  // set of referenced images
723 
724  FOREACH(statement, s, rstats)
725  {
726  // handle seqs in seqs with an explicit recursion
727  if (statement_sequence_p(s))
729  else if (freia_statement_aipo_call_p(s))
730  {
732  const freia_api_t * api =
734  if (api->arg_img_out==1)
735  {
737  //fprintf(stderr, "considering %s on %s\n",
738  // api->function_name, entity_local_name(img));
739  if (!set_belong_p(referenced, img) &&
740  // hey, we keep written parameters!
741  // ??? what about global images, if any?
742  !formal_parameter_p(img))
743  {
744  changed = true;
747  }
748  }
749  }
750  // update seen variables, but must skip deallocations!
751  // ??? what about skipping alloc as well?
752  if (!is_freia_dealloc(s))
754  // could also do loop indexes, but no images
756  // also look in initializations
760 
761  }
762 
763  gen_free_list(rstats);
764  }
765  return changed;
766 }
void free_instruction(instruction p)
Definition: ri.c:1118
const freia_api_t * hwac_freia_api(const char *function)
freia-utils.c
Definition: freia-utils.c:455
bool is_freia_dealloc(const statement s)
Definition: freia-utils.c:1007
static void collect_images(reference r, set referenced)
Definition: freia.c:705
#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
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
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
bool statement_sequence_p(statement)
Statement classes induced from instruction type.
Definition: statement.c:335
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 formal_parameter_p(entity)
Definition: variable.c:1489
#define instruction_sequence_p(x)
Definition: ri.h:1512
#define reference_domain
newgen_range_domain_defined
Definition: ri.h:338
#define sequence_statements(x)
Definition: ri.h:2360
#define instruction_sequence(x)
Definition: ri.h:1514
#define statement_instruction(x)
Definition: ri.h:2458
FREIA API function name -> SPoC hardware description (and others?)
Definition: freia.h:71
unsigned int arg_img_out
Definition: freia.h:79

References freia_api_t::arg_img_out, call_arguments, call_function, CAR, collect_images(), entity_initial, entity_local_name(), EXPRESSION, expression_to_entity(), FOREACH, formal_parameter_p(), free_instruction(), freia_statement_aipo_call_p(), freia_statement_to_call(), gen_context_recurse, gen_copy_seq(), gen_free_list(), gen_nreverse(), gen_true2(), hwac_freia_api(), instruction_sequence, instruction_sequence_p, is_freia_dealloc(), make_continue_instruction(), reference_domain, referenced, sequence_statements, set_belong_p(), statement_declarations, statement_instruction, and statement_sequence_p().

Referenced by freia_cleanup_main_sequence().

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

◆ freia_cleanup_status()

static void freia_cleanup_status ( statement  s,
set  helpers 
)
static

Definition at line 120 of file freia.c.

121 {
122  fcs_ctx ctx = { set_make(set_pointer), helpers };
123 
124  // cleanup statements
126 
127  // fix status variable initializations
129  {
131  {
133  entity_initial(var) =
135  }
136  }
137 
138  // cleanup
140 }
value make_value_expression(expression _field_)
Definition: ri.c:2850
void free_value(value p)
Definition: ri.c:2787
call freia_ok(void)
build all is well freia constant
Definition: freia-utils.c:695
static bool fcs_call_flt(call c, fcs_ctx *ctx)
Definition: freia.c:60
void gen_null2(__attribute__((unused)) void *u1, __attribute__((unused)) void *u2)
idem with 2 args, to please overpeaky compiler checks
Definition: genClib.c:2758
#define SET_FOREACH(type_name, the_item, the_set)
enumerate set elements in their internal order.
Definition: newgen_set.h:78
expression call_to_expression(call c)
Build an expression that call a function or procedure.
Definition: expression.c:309
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
Definition: freia.c:53

References call_domain, call_to_expression(), entity_initial, fcs_call_flt(), free_value(), freia_ok(), gen_context_recurse, gen_null2(), make_value_expression(), SET_FOREACH, set_free(), set_make(), set_pointer, fcs_ctx::used_for_status, and value_unknown_p.

Referenced by freia_compile().

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

◆ freia_cmp_statement()

static int freia_cmp_statement ( const statement s1,
const statement s2 
)
static

order two statements for qsort.

s1 before s2 => -1

Definition at line 279 of file freia.c.

280 {
281  const call
282  c1 = statement_call_p(*s1)?
284  c2 = statement_call_p(*s2)?
286  bool
287  s1r = c1? ENTITY_C_RETURN_P(call_function(c1)): false,
288  s2r = c2? ENTITY_C_RETURN_P(call_function(c2)): false,
289  s1a = is_freia_alloc(*s1), s2a = is_freia_alloc(*s2),
290  s1d = is_freia_dealloc(*s1), s2d = is_freia_dealloc(*s2);
291  if (s1r || s2r) pips_assert("one return in sequence", s1r ^ s2r);
292 
293  pips_debug(9, "%"_intFMT" %s is %d %d %d\n", statement_number(*s1),
294  c1? entity_name(call_function(c1)): "", s1r, s1a, s1d);
295  pips_debug(9, "%"_intFMT" %s is %d %d %d\n", statement_number(*s2),
296  c2? entity_name(call_function(c2)): "", s2r, s2a, s2d);
297 
298  int order = 0;
299  string why = "";
300 
301  // return at the back, obviously...
302  if (s1r) order = 1, why = "return1";
303  else if (s2r) order = -1, why = "return2";
304  // allocs at the front (there may be in initialisations, which up front)
305  else if (s1a && !s2a) order = -1, why = "alloc1";
306  else if (s2a && !s1a) order = 1, why = "alloc2";
307  // deallocs at the back
308  else if (s1d && !s2d) order = 1, why = "free1";
309  else if (s2d && !s1d) order = -1, why = "free2";
310  // else keep statement initial order
311  else order = statement_number(*s1)-statement_number(*s2), why = "stat";
312 
313  pips_assert("total order", order!=0);
314 
315  pips_debug(7, "%"_intFMT" %s %"_intFMT" (%s)\n", statement_number(*s1),
316  order==-1? "<": ">", statement_number(*s2), why);
317 
318  return order;
319 }
bool is_freia_alloc(const statement s)
Definition: freia-utils.c:1002
bool statement_call_p(statement)
Definition: statement.c:364
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define _intFMT
Definition: newgen_types.h:57
#define false
Definition: newgen_types.h:80
#define ENTITY_C_RETURN_P(e)
#define entity_name(x)
Definition: ri.h:2790
#define instruction_call(x)
Definition: ri.h:1529
#define statement_number(x)
Definition: ri.h:2452
s1
Definition: set.c:247

References _intFMT, call_function, ENTITY_C_RETURN_P, entity_name, instruction_call, is_freia_alloc(), is_freia_dealloc(), pips_assert, pips_debug, s1, statement_call_p(), statement_instruction, and statement_number.

Referenced by sort_subsequence().

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

◆ freia_compile()

string freia_compile ( string  module,
statement  mod_stat,
string  target 
)

freia_compile: compile freia module & statement for target

  • do some cleanup on sequences
  • collect sequences of freia operations
  • create file for generated functions
  • call hardware-specific code generation for each sequence
Parameters
moduleodule
mod_statod_stat
targetarget

Definition at line 785 of file freia.c.

786 {
787  pips_assert("we need some dependable effects for our purpose",
788  !get_bool_property("CONSTANT_PATH_EFFECTS"));
789 
790  if (!freia_valid_target_p(target))
791  pips_internal_error("unexpected target %s", target);
792 
793  // deal with some simple image shuff cases by forward substitution
795 
796  // check for remaining image shuffles...
797  set shuffled = set_make(set_pointer);
798  if (freia_image_shuffle(mod_stat, shuffled))
799  {
800  if (get_bool_property("FREIA_ALLOW_IMAGE_SHUFFLE"))
801  pips_user_warning("image shuffle found in %s, "
802  "freia compilation may result in wrong code!\n",
803  module);
804  else
805  pips_user_error("image shuffle found in %s, "
806  "see FREIA_ALLOW_IMAGE_SHUFFLE property to continue.\n",
807  module);
808  }
809 
810  // freia_aipo_cast -> freia_aipo_copy before further compilation
811  if (get_bool_property("FREIA_CAST_IS_COPY"))
813 
814  freia_info fsi =
817 
818  // collect freia api functions...
820  // collect sequences
823  // just count potential enclosing loops...
828  NULL);
829 
830  // check safe return
831  pips_assert("loop count back to zero", fsi.enclosing_loops==0);
832 
833  // sort sequences by increasing statement numbers
834  fsi_sort(fsi.seqs);
835 
836  // output file if any
837  string file = NULL;
838  set helpers = NULL;
839  FILE * helper = NULL;
840  if (freia_spoc_p(target) || freia_terapix_p(target) ||
841  freia_opencl_p(target) || freia_sigmac_p(target) || freia_mppa_p(target))
842  {
843  file = helper_file_name(module, "c");
844  if (file_readable_p(file))
845  pips_user_error("file '%s' already exists: "
846  "cannot reapply transformation\n", file);
847  helper = safe_fopen(file, "w");
848  pips_debug(1, "generating file '%s'\n", file);
849 
850  // we will also record created helpers
851  helpers = set_make(set_pointer);
852  }
853 
854  // headers
855  if (freia_spoc_p(target))
856  fprintf(helper, "%s", FREIA_SPOC_INCLUDES);
857  else if (freia_terapix_p(target))
858  fprintf(helper, "%s", FREIA_TRPX_INCLUDES);
859  else if (freia_opencl_p(target))
860  fprintf(helper, "%s", FREIA_OPENCL_INCLUDES);
861  else if (freia_sigmac_p(target))
862  fprintf(helper, "%s", FREIA_SIGMAC_INCLUDES);
863  else if (freia_mppa_p(target))
864  fprintf(helper, "%s", FREIA_MPPA_INCLUDES);
865 
866  // hmmm... should rely on use-defs
867  hash_table occs = freia_build_image_occurrences(mod_stat, NULL, NULL, NULL);
868  set output_images = freia_compute_current_output_images();
869  // hmmm... panic mode
870  set_union(output_images, output_images, shuffled);
871 
872  // first explicitely build and fix the list of dags,
873  // with some reverse order hocus-pocus for outputs computations...
874  list lsi = gen_nreverse(gen_copy_seq(fsi.seqs));
875  list ldags = NIL;
876  int n_dags = gen_length(fsi.seqs);
877  FOREACH(list, ls, lsi)
878  {
879  dag d = freia_build_dag(module, ls, --n_dags, occs, output_images, ldags,
880  set_belong_p(fsi.in_loops, ls));
881  ldags = CONS(dag, d, ldags);
882  }
883  gen_free_list(lsi), lsi = NIL;
884 
885  list lcurrent = ldags;
886  // signatures definition must be cross-dag because of
887  // dilate/erode helper reuse with OpenCL
888  hash_table signatures = hash_table_make(hash_pointer, 0);
889  n_dags = 0;
890  bool compile_lone = get_bool_property("FREIA_COMPILE_LONE_OPERATIONS");
891  FOREACH(list, ls, fsi.seqs)
892  {
893  // get corresponding dag, which should be destroyed by the called compiler
894  dag d = DAG(CAR(lcurrent));
895  lcurrent = CDR(lcurrent);
896 
897  // maybe skip lone operations
898  if (!compile_lone && gen_length(ls)==1)
899  {
900  n_dags++;
901  gen_free_list(ls);
902  continue;
903  }
904 
905  list allocated = NIL;
906  hash_table exchanges = NULL;
907  sequence sq = NULL;
908  if (hash_defined_p(fsi.sequence, ls))
909  {
910  exchanges = hash_table_make(hash_pointer, 0);
911  sq = hash_get(fsi.sequence, ls);
912  }
913 
914  if (freia_spoc_p(target))
915  allocated = freia_spoc_compile_calls(module, d, sq, ls, occs, exchanges,
916  output_images, helper, helpers, n_dags);
917  else if (freia_terapix_p(target))
918  allocated = freia_trpx_compile_calls(module, d, sq, ls, occs, exchanges,
919  output_images, helper, helpers, n_dags);
920  else if (freia_opencl_p(target))
921  allocated = freia_opencl_compile_calls(module, d, sq, ls, occs, exchanges,
922  output_images, helper, helpers, n_dags, signatures);
923  else if (freia_sigmac_p(target))
924  allocated = freia_sigmac_compile_calls(module, d, sq, ls, occs, exchanges,
925  output_images, helper, helpers, n_dags, gen_length(fsi.seqs));
926  else if (freia_mppa_p(target))
927  allocated =
928  freia_mppa_compile_calls(module, d, sq, ls, occs, exchanges,
929  output_images, helper, helpers, n_dags);
930  else if (freia_aipo_p(target))
931  allocated = freia_aipo_compile_calls(module, d, ls, occs, exchanges,
932  n_dags);
933 
934  if (exchanges)
935  {
937  HASH_FOREACH(dagvtx, v1, dagvtx, v2, exchanges)
939  }
940 
941  if (allocated)
942  {
943  FOREACH(entity, img, allocated)
945  gen_free_list(allocated);
946  }
947 
948  n_dags++;
949 
950  // cleanup list contents on the fly
951  gen_free_list(ls);
952  free_dag(d);
953  if (exchanges) hash_table_free(exchanges);
954  }
955 
956  // some code cleanup
958 
959  // some more code cleanup
960  if (get_bool_property("FREIA_CLEANUP_STATUS"))
961  // remove err = or err |= freia & helper functions
962  freia_cleanup_status(mod_stat, helpers);
963 
964  // cleanup
967  set_free(output_images), output_images = NULL;
968  set_free(shuffled), shuffled = NULL;
969  if (helpers) set_free(helpers), helpers = NULL;
970  gen_free_list(fsi.seqs);
971  set_free(fsi.in_loops);
973  hash_table_free(signatures);
974  gen_free_list(ldags);
975  if (helper) safe_fclose(helper, file);
976 
977  return file;
978 }
void free_dag(dag p)
dag freia_build_dag(string module, list ls, int number, const hash_table occurrences, const set output_images, const list ld, bool inloop)
build a full dag from list of statements ls.
Definition: dag-utils.c:2476
statement dagvtx_statement(const dagvtx v)
return statement if any, or NULL (for input nodes).
Definition: dag-utils.c:56
FILE * safe_fopen(const char *filename, const char *what)
Definition: file.c:67
int safe_fclose(FILE *stream, const char *filename)
Definition: file.c:77
bool file_readable_p(char *name)
Definition: file.c:428
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
string helper_file_name(string func_name, string suffix)
return malloc'ed "foo.database/Src/%{module}_helper_functions.c" should it depend on the target?...
Definition: freia-utils.c:2029
hash_table freia_build_image_occurrences(statement s, set image_occs_stats, hash_table image_stats, const hash_table signatures)
Definition: freia-utils.c:1388
void freia_close_dep_cache(void)
Definition: freia-utils.c:915
void freia_init_dep_cache(void)
Definition: freia-utils.c:909
set freia_compute_current_output_images(void)
Definition: freia-utils.c:1885
void freia_clean_image_occurrences(hash_table occs)
cleanup occurrence data structure
Definition: freia-utils.c:1407
static bool freia_image_shuffle(statement s, set shuffled)
Definition: freia.c:169
static bool fsi_stmt_flt(statement s, freia_info *fsip)
detect one lone aipo statement out of a sequence...
Definition: freia.c:542
static bool fsi_seq_flt(sequence sq, freia_info *fsip)
consider a sequence
Definition: freia.c:559
static bool fsi_loop_flt(__attribute__((unused)) gen_chunk *o, freia_info *fsip)
Definition: freia.c:463
static void fsi_sort(list lls)
Definition: freia.c:687
static void switch_cast_to_copy(statement s)
switch all image casts to image copies in "s"
Definition: freia.c:190
static bool freia_cleanup_main_sequence(statement modstat)
Definition: freia.c:768
static void freia_cleanup_status(statement s, set helpers)
Definition: freia.c:120
static void fsi_loop_rwt(__attribute__((unused)) gen_chunk *o, freia_info *fsip)
Definition: freia.c:470
#define freia_opencl_p(s)
Definition: freia.h:61
#define freia_sigmac_p(s)
Definition: freia.h:62
#define freia_mppa_p(s)
Definition: freia.h:63
#define freia_aipo_p(s)
Definition: freia.h:58
#define freia_spoc_p(s)
Definition: freia.h:59
#define freia_terapix_p(s)
Definition: freia.h:60
#define freia_valid_target_p(s)
Definition: freia.h:65
list freia_aipo_compile_calls(string module, dag fulld, list ls, const hash_table occs, hash_table exchanges, int number)
freia_aipo.c
Definition: freia_aipo.c:49
list freia_mppa_compile_calls(string module, dag fulld, sequence sq, list ls, const hash_table occs, hash_table exchanges, const set output_images, FILE *helper_file, __attribute__((__unused__)) set helpers, int number)
Compile one dag with AIPO optimizations.
Definition: freia_mppa.c:711
#define FREIA_MPPA_INCLUDES
Definition: freia_mppa.h:26
list freia_opencl_compile_calls(string module, dag fulld, sequence sq, list ls, const hash_table occs, hash_table exchanges, const set output_images, FILE *helper_file, set helpers, int number, hash_table signatures)
freia_opencl.c
#define FREIA_OPENCL_INCLUDES
Definition: freia_opencl.h:40
static int n_dags
Definition: freia_sigmac.c:56
#define FREIA_SIGMAC_INCLUDES
Definition: freia_sigmac.h:41
list freia_spoc_compile_calls(string module, dag fulld, sequence sq, list ls, const hash_table occs, hash_table exchanges, const set output_images, FILE *helper_file, set helpers, int number)
generate helpers for statements in ls of module output resulting functions in helper,...
Definition: freia_spoc.c:2247
#define FREIA_SPOC_INCLUDES
Definition: freia_spoc.h:188
#define DAG(x)
newgen_vtxcontent_domain_defined
list freia_trpx_compile_calls(string module, dag fulld, sequence sq, list ls, const hash_table occs, hash_table exchanges, const set output_images, FILE *helper_file, set helpers, int number)
do compile a list of statements for terapix
#define FREIA_TRPX_INCLUDES
Definition: freia_terapix.h:54
void freia_shuffle_move_forward(statement s)
void gen_context_multi_recurse(void *o, void *context,...)
Multi-recursion with context function visitor.
Definition: genClib.c:3373
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
void gen_exchange_in_list(list l, const void *i1, const void *i2)
exchange items i1 & i2 in the list
Definition: list.c:651
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
statement add_declaration_statement(statement, entity)
Definition: statement.c:2790
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:449
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
bool hash_defined_p(const hash_table htp, const void *key)
true if key has e value in htp.
Definition: hash.c:484
list freia_sigmac_compile_calls(string, dag, sequence, list, const hash_table, hash_table, const set, FILE *, set, int, int)
freia_sigmac.c
static statement mod_stat
We want to keep track of the current statement inside the recurse.
Definition: impact_check.c:41
#define pips_user_warning
Definition: misc-local.h:146
#define pips_internal_error
Definition: misc-local.h:149
#define pips_user_error
Definition: misc-local.h:147
@ hash_pointer
Definition: newgen_hash.h:32
#define HASH_FOREACH(key_type, k, value_type, v, ht)
Definition: newgen_hash.h:71
set set_union(set, const set, const set)
Definition: set.c:211
static char * module
Definition: pips.c:74
#define forloop_domain
newgen_extensions_domain_defined
Definition: ri.h:178
#define unstructured_domain
newgen_type_domain_defined
Definition: ri.h:442
#define loop_domain
newgen_language_domain_defined
Definition: ri.h:218
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define whileloop_domain
newgen_variable_domain_defined
Definition: ri.h:466
#define sequence_domain
newgen_reference_domain_defined
Definition: ri.h:346
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
list seqs
Definition: freia.c:453
hash_table sequence
Definition: freia.c:455
int enclosing_loops
Definition: freia.c:457
set in_loops
Definition: freia.c:460

References add_declaration_statement(), CAR, CDR, CONS, DAG, dagvtx_statement(), freia_info::enclosing_loops, file_readable_p(), FOREACH, forloop_domain, fprintf(), free_dag(), freia_aipo_compile_calls(), freia_aipo_p, freia_build_dag(), freia_build_image_occurrences(), freia_clean_image_occurrences(), freia_cleanup_main_sequence(), freia_cleanup_status(), freia_close_dep_cache(), freia_compute_current_output_images(), freia_image_shuffle(), freia_init_dep_cache(), freia_mppa_compile_calls(), FREIA_MPPA_INCLUDES, freia_mppa_p, freia_opencl_compile_calls(), FREIA_OPENCL_INCLUDES, freia_opencl_p, freia_shuffle_move_forward(), freia_sigmac_compile_calls(), FREIA_SIGMAC_INCLUDES, freia_sigmac_p, freia_spoc_compile_calls(), FREIA_SPOC_INCLUDES, freia_spoc_p, freia_terapix_p, freia_trpx_compile_calls(), FREIA_TRPX_INCLUDES, freia_valid_target_p, fsi_loop_flt(), fsi_loop_rwt(), fsi_seq_flt(), fsi_sort(), fsi_stmt_flt(), gen_context_multi_recurse(), gen_copy_seq(), gen_exchange_in_list(), gen_free_list(), gen_length(), gen_nreverse(), gen_null(), get_bool_property(), hash_defined_p(), HASH_FOREACH, hash_get(), hash_pointer, hash_table_free(), hash_table_make(), helper_file_name(), freia_info::in_loops, loop_domain, mod_stat, module, n_dags, NIL, pips_assert, pips_debug, pips_internal_error, pips_user_error, pips_user_warning, safe_fclose(), safe_fopen(), freia_info::seqs, freia_info::sequence, sequence_domain, sequence_statements, set_belong_p(), set_free(), set_make(), set_pointer, set_union(), statement_domain, switch_cast_to_copy(), unstructured_domain, and whileloop_domain.

Referenced by freia_compiler().

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

◆ freia_image_shuffle()

static bool freia_image_shuffle ( statement  s,
set  shuffled 
)
static
Returns
whether there is an image shuffle, i.e. image pointer assignments

Definition at line 169 of file freia.c.

170 {
171  fis_ctx ctx = { shuffled };
173  return set_size(shuffled)!=0;
174 }
static bool fis_call_flt(call c, fis_ctx *ctx)
Definition: freia.c:148
int set_size(const set)
returns the number of items in s.
Definition: set.c:359
Definition: freia.c:144

References call_domain, fis_call_flt(), gen_context_recurse, gen_null2(), and set_size().

Referenced by freia_compile().

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

◆ freia_is_transpose_call()

bool freia_is_transpose_call ( statement  s)

Detect a call to a se transposition function and transpose the arguments.

The expected function should have the following signature transpose_func(int kernelOut[9], const int kernelIn[9], ...)

Definition at line 499 of file freia.c.

499  {
500 
501  if (statement_call_p(s)) {
502  call c = statement_call(s);
503  if (c) {
504  entity called = call_function(c);
505 
506  // extract transposition calls
507  if (same_string_p(entity_local_name(called),
508  get_string_property("FREIA_TRANSPOSE_KERNEL_FUNC"))) {
509 
510  list args = call_arguments(c);
511  pips_assert("an expected transposition function should have at least "
512  "two arguments",
513  gen_length(args) >= 2);
514 
515  // get the argument entities
517  entity trse = expression_to_entity(EXPRESSION(CAR(args)));
518 
520  // get the expression value of the initial structuring element
522  // effectively transpose structuring element
523  expression trseval = freia_transpose_kernel(seval);
524 
525  // set the value of the transposed structuring element
526  set_entity_initial(trse, trseval);
527 
528  pips_debug(9, "%s: out %s, in %s\n", entity_local_name(called),
529  expression_to_string(trseval),
530  expression_to_string(seval));
531  }
532 
533  return true;
534  }
535  }
536  }
537  return false;
538 }
void set_entity_initial(entity, expression)
Be careful if the initial value has already been set.
Definition: util.c:3469
char * get_string_property(const char *)
expression freia_transpose_kernel(const expression se)
Transpose a structuring element expression.
Definition: freia.c:479
call statement_call(statement)
Get the call of a statement.
Definition: statement.c:1406
string expression_to_string(expression e)
Definition: expression.c:77

References call_arguments, call_function, CAR, CDR, entity_initial, entity_local_name(), EXPRESSION, expression_to_entity(), expression_to_string(), freia_transpose_kernel(), gen_length(), get_string_property(), pips_assert, pips_debug, same_string_p, set_entity_initial(), statement_call(), statement_call_p(), value_expression, and value_expression_p.

Referenced by fsi_stmt_flt().

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

◆ freia_some_effects_on_images()

bool freia_some_effects_on_images ( statement  s)

tell whether a statement has no effects on images.

freia.c

if so, it may be included somehow in the pipeline and just skipped, provided stat scalar dependencies are taken care of.

Definition at line 402 of file freia.c.

403 {
404  int img_effect = false;
406  FOREACH(effect, e, cumu)
407  {
409  {
410  img_effect = true;
411  break;
412  }
413  }
414  return img_effect;
415 }
effects load_cumulated_rw_effects(statement)
#define effect_variable(e)
For COMPATIBILITY purpose only - DO NOT USE anymore.
#define effects_effects(x)
Definition: effects.h:710

References effect_variable, effects_effects, FOREACH, freia_image_variable_p(), and load_cumulated_rw_effects().

Referenced by fsi_seq_flt().

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

◆ freia_stmt_free_p()

static bool freia_stmt_free_p ( const statement  s)
static

Definition at line 202 of file freia.c.

203 {
205  const char* called = c? entity_user_name(call_function(c)): "";
206  return same_string_p(called, FREIA_FREE);
207 }

References call_function, entity_user_name(), FREIA_FREE, freia_statement_to_call(), and same_string_p.

Referenced by fsi_seq_flt().

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

◆ freia_transpose_kernel()

expression freia_transpose_kernel ( const expression  se)

Transpose a structuring element expression.

Parameters
see

Definition at line 479 of file freia.c.

479  {
480  // get the structuring element array
483 
484  // reverse it...
485  list vals_rev = gen_nreverse(gen_full_copy_list(vals));
486 
487  // build the expression
488  return make_expression(make_syntax_call(make_call(fun, vals_rev)),
490 }
call make_call(entity a1, list a2)
Definition: ri.c:269
syntax make_syntax_call(call _field_)
Definition: ri.c:2500
expression make_expression(syntax a1, normalized a2)
Definition: ri.c:886
list gen_full_copy_list(list l)
Copy a list structure with element copy.
Definition: list.c:535
#define expression_normalized(x)
Definition: ri.h:1249

References call_arguments, call_function, expression_normalized, expression_syntax, gen_full_copy_list(), gen_nreverse(), make_call(), make_expression(), make_syntax_call(), and syntax_call.

Referenced by freia_is_transpose_call().

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

◆ fsi_cmp()

static int fsi_cmp ( const list l1,
const list l2 
)
static

Definition at line 681 of file freia.c.

682 {
683  return (int) ((_int) hash_get(fsi_number, *l1) -
684  (_int) hash_get(fsi_number, *l2));
685 }
static hash_table fsi_number
Definition: freia.c:679

References fsi_number, and hash_get().

Referenced by fsi_sort().

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

◆ fsi_loop_flt()

static bool fsi_loop_flt ( __attribute__((unused)) gen_chunk o,
freia_info fsip 
)
static

Definition at line 463 of file freia.c.

465 {
466  fsip->enclosing_loops++;
467  return true;
468 }

References freia_info::enclosing_loops.

Referenced by freia_compile().

+ Here is the caller graph for this function:

◆ fsi_loop_rwt()

static void fsi_loop_rwt ( __attribute__((unused)) gen_chunk o,
freia_info fsip 
)
static

Definition at line 470 of file freia.c.

472 {
473  fsip->enclosing_loops--;
474 }

References freia_info::enclosing_loops.

Referenced by freia_compile().

+ Here is the caller graph for this function:

◆ fsi_seq_flt()

static bool fsi_seq_flt ( sequence  sq,
freia_info fsip 
)
static

consider a sequence

of statements

Definition at line 559 of file freia.c.

560 {
561  pips_debug(9, "considering sequence...\n");
562 
563  list /* of statements */ ls = NIL, ltail = NIL, lup = NIL;
564 
565  // use a copy, because the sequence is rewritten inside the loop...
566  // see sort_subsequence. I guess should rather delay it...
568 
570 
571  FOREACH(statement, s, lseq)
572  {
573  bool freia_api = freia_statement_aipo_call_p(s);
574  // the statement is kept if
575  bool keep_stat =
576  // it is an AIPO call
577  freia_api ||
578  // it follows kept calls and
579  (ls && (
580  // it is an (image) allocation in the middle of the code
581  freia_alloc_stat_p(s) ||
582  // or it has no image effects
584 
585  // quick fix for performance: stop on timer calls
586  if (keep_stat && statement_call_p(s))
587  {
588  entity called = call_function(statement_call(s));
589  if (same_string_p(entity_local_name(called), "gettimeofday") ||
590  same_string_p(entity_local_name(called), "freia_common_wait"))
591  keep_stat = false;
592  }
593 
594  pips_debug(7, "statement %"_intFMT": %skept\n",
595  statement_number(s), keep_stat? "": "not ");
596 
597  // FREIA API & "intermediate" statements are kept
598  if (keep_stat)
599  {
600  if (freia_api)
601  {
602  ls = gen_nconc(ltail, ls), ltail = NIL;
603  ls = CONS(statement, s, ls);
605  }
606  else // else accumulate in the "other list" waiting for something...
607  {
608  if (statement_depends_p(written, s) ||
609  (statement_call_p(s) &&
611  // free are kept in the tail... not caught as a W effect?
613  {
614  pips_debug(8, "statement %d in ltail\n", (int) statement_number(s));
615  ltail = CONS(statement, s, ltail);
617  }
618  else
619  {
620  pips_debug(8, "statement %d in lup\n", (int) statement_number(s));
621  // we can move it up...
622  lup = CONS(statement, s, lup);
623  }
624  }
625  }
626  else // the sequence must be cut on this statement
627  {
628  if (lup && ls)
629  move_ahead(lup, STATEMENT(CAR(gen_last(ls))), sq);
630  if (lup) gen_free_list(lup), lup = NIL;
631  if (ls!=NIL)
632  {
633  sort_subsequence(ls, sq);
635  fsip->seqs = CONS(list, ls, fsip->seqs);
636  hash_put(fsip->sequence, ls, sq);
637  if (fsip->enclosing_loops)
638  set_add_element(fsip->in_loops, fsip->in_loops, ls);
639  ls = NIL;
640  }
641  if (ltail) gen_free_list(ltail), ltail = NIL;
643  }
644  }
645 
646  // end of sequence reached
647  if (ls!=NIL)
648  {
649  if (lup && ls)
650  move_ahead(lup, STATEMENT(CAR(gen_last(ls))), sq);
651  sort_subsequence(ls, sq);
653  fsip->seqs = CONS(list, ls, fsip->seqs);
654  hash_put(fsip->sequence, ls, sq);
655  if (fsip->enclosing_loops)
656  set_add_element(fsip->in_loops, fsip->in_loops, ls);
657  ls = NIL;
658  }
659 
660  // cleanup
661  if (ltail) gen_free_list(ltail), ltail = NIL;
662  if (lup) gen_free_list(lup), lup = NIL;
663  gen_free_list(lseq);
664  set_free(written);
665  return true;
666 }
static bool written
Definition: alias_check.c:512
static bool statement_depends_p(set written, statement s)
Definition: freia.c:434
static void update_written_variables(set written, statement s)
update the set of written variables, as seen from effects, with a statement this is really to rebuild...
Definition: freia.c:421
bool freia_some_effects_on_images(statement s)
tell whether a statement has no effects on images.
Definition: freia.c:402
static list clean_statement_list_for_aipo(list ls)
remove unrelated stuff at head & tail, so that it does not come in later on and possibly trouble the ...
Definition: freia.c:343
static bool freia_alloc_stat_p(const statement s)
Definition: freia.c:217
static void sort_subsequence(list ls, sequence sq)
reorder a little bit statements, so that allocs & deallocs are up front or in the back,...
Definition: freia.c:351
static bool freia_stmt_free_p(const statement s)
Definition: freia.c:202
static void move_ahead(list ls, statement target, sequence sq)
move statements in l ahead of s in sq note that ls is in reverse order...
Definition: freia.c:247
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
list gen_last(list l)
Return the last element of a list.
Definition: list.c:578
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
set set_clear(set)
Assign the empty set to s s := {}.
Definition: set.c:326

References _intFMT, call_function, CAR, clean_statement_list_for_aipo(), CONS, freia_info::enclosing_loops, ENTITY_C_RETURN_P, entity_local_name(), FOREACH, freia_alloc_stat_p(), freia_some_effects_on_images(), freia_statement_aipo_call_p(), freia_stmt_free_p(), gen_copy_seq(), gen_free_list(), gen_last(), gen_nconc(), hash_put(), freia_info::in_loops, move_ahead(), NIL, pips_debug, same_string_p, freia_info::seqs, freia_info::sequence, sequence_statements, set_add_element(), set_clear(), set_free(), set_make(), set_pointer, sort_subsequence(), STATEMENT, statement_call(), statement_call_p(), statement_depends_p(), statement_number, update_written_variables(), and written.

Referenced by freia_compile().

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

◆ fsi_sort()

static void fsi_sort ( list  lls)
static

Definition at line 687 of file freia.c.

688 {
689  pips_assert("static fsi_number is clean", !fsi_number);
691  FOREACH(list, ls, lls)
692  hash_put(fsi_number, ls, (void*) min_statement(ls));
695 }
static _int min_statement(list ls)
Definition: freia.c:670
static int fsi_cmp(const list *l1, const list *l2)
Definition: freia.c:681
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
int(* gen_cmp_func_t)(const void *, const void *)
Definition: newgen_types.h:114

References FOREACH, fsi_cmp(), fsi_number, gen_sort_list(), hash_pointer, hash_put(), hash_table_free(), hash_table_make(), min_statement(), and pips_assert.

Referenced by freia_compile().

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

◆ fsi_stmt_flt()

static bool fsi_stmt_flt ( statement  s,
freia_info fsip 
)
static

detect one lone aipo statement out of a sequence...

Definition at line 542 of file freia.c.

543 {
546  {
548  if (i && instruction_sequence_p(i)) return false;
549  // not a sequence handled by fsi_seq_flt...
550  list ls = CONS(statement, s, NIL);
551  fsip->seqs = CONS(list, ls, fsip->seqs);
552  if (fsip->enclosing_loops)
553  set_add_element(fsip->in_loops, fsip->in_loops, ls);
554  }
555  return true;
556 }
bool freia_is_transpose_call(statement s)
Detect a call to a se transposition function and transpose the arguments.
Definition: freia.c:499
gen_chunk * gen_get_ancestor(int, const void *)
return the first ancestor object found of the given type.
Definition: genClib.c:3560
#define instruction_domain
newgen_functional_domain_defined
Definition: ri.h:202
struct _newgen_struct_instruction_ * instruction
Definition: ri.h:207

References CONS, freia_info::enclosing_loops, freia_is_transpose_call(), freia_statement_aipo_call_p(), gen_get_ancestor(), freia_info::in_loops, instruction_domain, instruction_sequence_p, NIL, freia_info::seqs, and set_add_element().

Referenced by freia_compile().

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

◆ min_statement()

static _int min_statement ( list  ls)
static

Definition at line 670 of file freia.c.

671 {
672  _int min = -1;
673  FOREACH(statement, s, ls)
674  min = (min==-1)? statement_number(s):
676  return min;
677 }
#define min(a, b)

References FOREACH, min, and statement_number.

Referenced by fsi_sort().

+ Here is the caller graph for this function:

◆ move_ahead()

static void move_ahead ( list  ls,
statement  target,
sequence  sq 
)
static

move statements in l ahead of s in sq note that ls is in reverse order...

Definition at line 247 of file freia.c.

248 {
249  // for faster list inclusion test
250  set tomove = set_make(set_pointer);
251  set_append_list(tomove, ls);
252 
253  // build new sequence list in reverse order
254  list nsq = NIL;
256  {
257  if (set_belong_p(tomove, s))
258  continue; // skip!
259  if (s==target)
260  // insert list now!
261  nsq = gen_nconc(gen_copy_seq(ls), nsq);
262  // and keep current statement
263  nsq = CONS(statement, s, nsq);
264  }
265 
266  // update sequence with new list
269 
270  // clean up
271  set_free(tomove);
272 }
set set_append_list(set, const list)
add list l items to set s, which is returned.
Definition: set.c:460

References CONS, FOREACH, gen_copy_seq(), gen_free_list(), gen_nconc(), gen_nreverse(), NIL, sequence_statements, set_append_list(), set_belong_p(), set_free(), set_make(), and set_pointer.

Referenced by fsi_seq_flt().

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

◆ sctc_call_rwt()

static void sctc_call_rwt ( call  c,
int count 
)
static

Definition at line 178 of file freia.c.

179 {
180  entity func = call_function(c);
181  if (same_string_p(entity_local_name(func), AIPO "cast"))
182  {
184  (*count)++;
185  }
186 }
#define AIPO
Definition: freia.h:51
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

References AIPO, call_function, entity_local_name(), local_name_to_top_level_entity(), and same_string_p.

Referenced by switch_cast_to_copy().

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

◆ sort_subsequence()

static void sort_subsequence ( list  ls,
sequence  sq 
)
static

reorder a little bit statements, so that allocs & deallocs are up front or in the back, and may be removed by the previous function.

Definition at line 351 of file freia.c.

352 {
353  ifdebug(8) {
354  pips_debug(8, "input: ");
355  gen_fprint(stderr, "ls", ls, (gen_string_func_t) stmt_nb);
356  }
357 
358  set cmp = set_make(set_pointer);
359  set_assign_list(cmp, ls);
360 
361  // sort ls
363 
364  // extract sub sequence in a separate list
365  list head = NIL, lcmp = NIL, tail = NIL;
367  {
368  if (set_belong_p(cmp, s))
369  lcmp = CONS(statement, s, lcmp);
370  else
371  if (!lcmp)
372  head = CONS(statement, s, head);
373  else
374  tail = CONS(statement, s, tail);
375  }
376 
377  // sort subsequence
379 
380  // rebuild sequence
382  sequence_statements(sq) =
383  gen_nconc(gen_nreverse(head), gen_nconc(lcmp, gen_nreverse(tail)));
384 
385  set_free(cmp);
386 
387  ifdebug(8) {
388  pips_debug(8, "output: ");
389  gen_fprint(stderr, "ls", ls, (gen_string_func_t) stmt_nb);
390  }
391 }
static int freia_cmp_statement(const statement *s1, const statement *s2)
order two statements for qsort.
Definition: freia.c:279
static string stmt_nb(void *s)
debug helper
Definition: freia.c:322
void gen_fprint(FILE *out, string name, const list l, gen_string_func_t item_name)
Definition: list.c:873
set set_assign_list(set, const list)
assigns a list contents to a set all duplicated elements are lost
Definition: set.c:474
string(* gen_string_func_t)(const void *)
Definition: newgen_types.h:111
#define ifdebug(n)
Definition: sg.c:47

References CONS, FOREACH, freia_cmp_statement(), gen_fprint(), gen_free_list(), gen_nconc(), gen_nreverse(), gen_sort_list(), ifdebug, NIL, pips_debug, sequence_statements, set_assign_list(), set_belong_p(), set_free(), set_make(), set_pointer, and stmt_nb().

Referenced by fsi_seq_flt().

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

◆ statement_depends_p()

static bool statement_depends_p ( set  written,
statement  s 
)
static
Returns
whether statement depends on some written variables

Definition at line 434 of file freia.c.

435 {
436  bool depends = false;
438  FOREACH(effect, e, cumu)
439  {
441  {
442  depends = true;
443  break;
444  }
445  }
446  return depends;
447 }
#define effect_read_p(eff)
#define effect_scalar_p(eff) entity_scalar_p(effect_entity(eff))

References effect_read_p, effect_variable, effects_effects, FOREACH, load_cumulated_rw_effects(), set_belong_p(), and written.

Referenced by fsi_seq_flt().

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

◆ stmt_nb()

static string stmt_nb ( void *  s)
static

debug helper

Definition at line 322 of file freia.c.

323 {
324  return i2a((int) statement_number((statement) s));
325 }
char * i2a(int)
I2A (Integer TO Ascii) yields a string for a given Integer.
Definition: string.c:121

References i2a(), and statement_number.

Referenced by sort_subsequence().

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

◆ switch_cast_to_copy()

static void switch_cast_to_copy ( statement  s)
static

switch all image casts to image copies in "s"

Definition at line 190 of file freia.c.

191 {
192  int count = 0;
194  // ??? I may have look into declarations? freia calls in declarations
195  // are not really implemented yet.
196  pips_user_warning("freia_cast switched to freia_copy: %d\n", count);
197 }
static int count
Definition: SDG.c:519
static void sctc_call_rwt(call c, int *count)
Definition: freia.c:178

References call_domain, count, gen_context_recurse, gen_true2(), pips_user_warning, and sctc_call_rwt().

Referenced by freia_compile().

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

◆ update_written_variables()

static void update_written_variables ( set  written,
statement  s 
)
static

update the set of written variables, as seen from effects, with a statement this is really to rebuild a poor's man dependency graph in order to move some statements around...

Definition at line 421 of file freia.c.

422 {
424  FOREACH(effect, e, cumu)
425  if (effect_write_p(e))
427  ifdebug(9)
428  set_fprint(stderr, "written", written,
430 }
#define effect_write_p(eff)
void set_fprint(FILE *, string, const set, gen_string_func_t)
print set s to file stream out.
Definition: set.c:524

References effect_variable, effect_write_p, effects_effects, entity_local_name(), FOREACH, ifdebug, load_cumulated_rw_effects(), set_add_element(), set_fprint(), and written.

Referenced by fsi_seq_flt().

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

Variable Documentation

◆ fsi_number

hash_table fsi_number = NULL
static

Definition at line 679 of file freia.c.

Referenced by fsi_cmp(), and fsi_sort().