PIPS
io-compile.c
Go to the documentation of this file.
1 /*
2 
3  $Id: io-compile.c 23065 2016-03-02 09:05:50Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 /* HPFC module by Fabien COELHO
28  */
29 
30 #include "defines-local.h"
31 
32 #include "semantics.h"
33 #include "conversion.h"
34 #include "effects-generic.h"
35 #include "effects-simple.h"
36 #include "effects-convex.h"
37 
38 /************************************************* IO EFFICIENT COMPILATION */
39 
40 
41 
42 /* OUT Regions(effects) are used to verify if the entity current_entity is
43 read in another statement later
44 (note that we don't need to know which statement is reading current_entity)*/
45 
46 static bool
48 {
49  list list_out;
50 
51  if (get_bool_property("HPFC_IGNORE_IN_OUT_REGIONS"))
52  /*IN & OUT Regions are not used*/
53  return true;
54 
55 
56 /* get OUT Regions(Effects) list for the io statement */
57 /* list_out = load_statement_out_regions(stat);*/
58 
59  list_out = load_out_effects_list(stat);
60 
61  ifdebug(2)
62  {
63  pips_debug(3, "OUT regions: \n");
64  print_regions(list_out);
65  }
66 
67 /* for all OUT Regions (Effects) for the statement stat,
68  test if reference in current_effect is egal to current_entity */
69 
70  MAP(EFFECT, current_effect,
71  {
72  if (effect_variable(current_effect)==current_entity)
73  return true;
74  },
75  list_out);
76 
77  return false;
78 }
79 
80 /* IN Regions(effects) are used to verify if the entity current_entity is
81 initialized before it's used in the io statement*/
82 
83 static bool
85 {
86  list list_in;
87 
88  if (get_bool_property("HPFC_IGNORE_IN_OUT_REGIONS")) /* & OUT Regions are not used*/
89  return true;
90 
91 /* get IN Regions(Effects) list for the io statement */
92 /* list_in = load_statement_in_regions(stat);*/
93 
94  list_in = load_in_effects_list(stat);
95 
96  ifdebug(2)
97  {
98  pips_debug(3, "IN regions: \n");
99  print_regions(list_in);
100  }
101 
102 /* for all IN Regions (Effects) for the statement stat,
103  test if reference in current_effect is egal to current_entity */
104 
105  MAP(EFFECT, current_effect,
106  {
107  if (effect_variable(current_effect)==current_entity)
108  return true;
109  },
110  list_in);
111 
112  return false;
113 }
114 
115 static Psysteme
117  statement stat,
118  tag move)
119 {
121  ((movement_collect_p(move)) ?
124 }
125 
126 void
128  Psysteme syst,
129  list scanners,
130  Psysteme *pcond,
131  Psysteme *penum)
132 {
133  Pbase base = entity_list_to_base(scanners);
134  algorithm_row_echelon_generic(syst, base, pcond, penum,
135  get_bool_property("HPFC_REDUNDANT_SYSTEMS_FOR_REMAPS"));
136  /* this should improve conditions? */
137  sc_find_equalities(pcond);
138  base_rm(base);
139 }
140 
141 
142 list /* of entity */
144  entity (*creation)(),
145  int number)
146 {
147  list result = NIL;
148 
149  for(;number>0;number--)
150  result = CONS(ENTITY, creation(number), result);
151 
152  return result;
153 }
154 
155 static Psysteme
157  entity array,
158  statement stat,
159  tag move,
160  tag act)
161 {
162  Psysteme
163  result = SC_UNDEFINED, /* ??? bug post with region */
164  region = effect_system(entity_to_region(stat, array, act)),
166  stamme = hpfc_unstutter_dummies(array),
167  contxt = statement_context(stat, move);
168 
169  pips_assert("distributed array", !array_distributed_p(array));
170 
171  result = sc_append(sc_rn(NULL), region);
172  result = sc_append(result, a_decl);
173  result = sc_append(result, stamme);
174  result = sc_append(result, contxt);
175 
176  DEBUG_SYST(8, concatenate("whole: ", entity_name(array), NULL), result);
177 
178  /* the noisy system is cleaned
179  * some variables are not used, they are removed here.
180  */
181  sc_nredund(&result);
182  base_rm(sc_base(result));
183  sc_base(result) = NULL;
184  sc_creer_base(result);
185 
186  DEBUG_SYST(7, "region", region);
187  DEBUG_SYST(7, "array declaration", a_decl);
188  DEBUG_SYST(7, "unstammer", stamme);
189  DEBUG_SYST(7, "context", contxt);
190 
191  DEBUG_SYST(6, concatenate("result: ", entity_name(array), NULL), result);
192 
193  return result;
194 }
195 
196 static Psysteme
198  entity array,
199  statement stat,
200  tag move,
201  tag act)
202 {
203  Psysteme result = SC_UNDEFINED,
204  /* ??? bug: the preconditions may be in the regions. To update, I
205  * should have the postconditions instead, that is the statement
206  * transformer should be applied to the system.
207  */
210  sother = hpfc_compute_unicity_constraints(array), /* ??? */
211  stamme = hpfc_unstutter_dummies(array),
212  contxt = statement_context(stat, move);
213 
214  /* ??? massive memory leak
215  polyhedron intersections
216 */
217  result = sc_append(sc_rn(NULL), region);
218  result = sc_append(result, dist_v);
219  result = sc_append(result, sother);
220  result = sc_append(result, stamme);
221  result = sc_append(result, contxt);
222 
223  DEBUG_SYST(8, concatenate("whole: ", entity_name(array), NULL), result);
224 
225  /* the noisy system is cleaned
226  * some variables are not used, they are removed here.
227  */
228  build_sc_nredund_2pass(&result);
229  base_rm(sc_base(result));
230  sc_base(result) = NULL;
231  sc_creer_base(result);
232 
233  DEBUG_SYST(9, "region", region);
234  DEBUG_SYST(9, "array syst", dist_v);
235  DEBUG_SYST(9, "hpf unicity", sother);
236  DEBUG_SYST(9, "unstammer", stamme);
237  DEBUG_SYST(9, "context", contxt);
238 
239  DEBUG_SYST(6, concatenate("result: ", entity_name(array), NULL), result);
240 
241  return(result);
242 }
243 
244 void
246  Psysteme *psyst,
247  list *plvars)
248 {
249  Psysteme syst = *psyst;
250  list kept = NIL;
251 
252  MAP(ENTITY, e,
253  {
254  Variable var = (Variable) e;
255  Value coeff = VALUE_MONE;
256 
257  (void) contrainte_var_min_coeff(sc_egalites(syst), var, &coeff, false);
258 
259  if (value_one_p(coeff))
260  {
261  Pvecteur v = vect_new(var, VALUE_ONE);
262  bool exact = true;
263 
264  pips_debug(7, "removing variable %s\n",
265  entity_local_name((entity) var));
266 
267  sc_projection_along_variables_with_test_ofl_ctrl
268  (&syst, v, &exact, NO_OFL_CTRL);
269 
270  pips_assert("exact projection", exact);
271  vect_rm(v);
272  }
273  else
274  kept = CONS(ENTITY, (entity) var, kept);
275  },
276  *plvars);
277 
278  base_rm(sc_base(syst)), sc_base(syst) = BASE_NULLE, sc_creer_base(syst);
279 
280  *psyst = syst;
281  gen_free_list(*plvars), *plvars=kept;
282 }
283 
284 static Psysteme
286  Psysteme syst,
287  entity array,
288  tag move)
289 {
290  int array_dim = NumberOfDimension(array);
291  list keep = NIL, try_keep = NIL, remove = NIL,
292  try_remove = base_to_list(sc_base(syst));
293 
294  pips_debug(5, "array %s, movement %s\n", entity_local_name(array),
295  (movement_collect_p(move))?"collect":"update");
296 
297  /* ALPHA_i's
298  * PHI_i's
299  */
301  add_to_list_of_vars(remove, get_ith_region_dummy, array_dim);
302 
303  /* keep parameters !
304  */
305  MAP(ENTITY, e,
306  {
307  const char* s = entity_module_name(e);
308 
309  if (strcmp(s, HPFC_PACKAGE) && strcmp(s, REGIONS_MODULE_NAME))
310  keep = CONS(ENTITY, e, keep);
311  },
312  try_remove);
313 
314  /* others
315  */
316  gen_remove(&try_remove, (entity) TCST);
317  MAP(ENTITY, e, gen_remove(&try_remove, e), keep);
318  MAP(ENTITY, e, gen_remove(&try_remove, e), try_keep);
319  MAP(ENTITY, e, gen_remove(&try_remove, e), remove);
320 
321  /* remove variables that have to be removed
322  */
323  MAP(ENTITY, e,
324  sc_projection_along_variable_ofl_ctrl(&syst, (Variable) e, NO_OFL_CTRL),
325  remove);
326 
327  /* Try to remove other unusefull variables
328  */
329  remove_variables_if_possible(&syst, &try_remove);
330 
331  /* the noisy system is cleaned
332  * some variables are not used, they are removed here.
333  */
334  build_sc_nredund_2pass(&syst);
335  base_rm(sc_base(syst));
336  sc_base(syst) = BASE_NULLE;
337  sc_creer_base(syst);
338 
339  DEBUG_SYST(6, entity_name(array), syst);
340 
341  return(syst);
342 }
343 
344 void
346  Psysteme *ps,
347  list /* of entity (Variable) */ *plv)
348 {
349  MAP(ENTITY, e,
350  {
351  pips_debug(8, "removing variable %s\n", entity_local_name(e));
352  sc_projection_along_variable_ofl_ctrl(ps, (Variable) e, NO_OFL_CTRL);
353  },
354  *plv);
355 
356  gen_free_list(*plv), *plv=NIL;
357 }
358 
359 void
361  Psysteme *ps,
362  list /* of entities */ *plrm,
363  list *pltry)
364 {
366  remove_variables_if_possible(ps, pltry);
367 
369  base_rm(sc_base(*ps)), sc_creer_base(*ps);
370 }
371 
372 static Psysteme
374  Psysteme syst, /* system to be cleaned */
375  entity array, /* io on array */
376  tag move) /* collect or update */
377 {
378  /* ??? what about the variables?
379  * some are usefull, some are constants, and others should
380  * be discarded. This selection and projection may be done here.
381  */
382  /* to be removed:
383  * PHIi...
384  * THETAi...
385  * some GAMMAi...
386  * some others coming from the *conditions
387  *
388  * loop generation on:
389  * PSIi...
390  * some GAMMAi...
391  * some DELTAi...
392  * complementary ALPHAi... (LALPHAi?)
393  */
394  entity
395  template = array_to_template(array),
396  processor = template_to_processors(template);
397  int
398  array_dim = NumberOfDimension(array),
399  template_dim = NumberOfDimension(template),
400  processor_dim = NumberOfDimension(processor);
401  list
402  keep = NIL, try_keep = NIL, remove = NIL,
403  try_remove = base_to_list(sc_base(syst));
404 
405  pips_debug(5, "array %s, movement %s\n", entity_local_name(array),
406  (movement_collect_p(move))?"collect":"update");
407 
408  pips_assert("distributed array", array_distributed_p(array));
409 
410  /* THETA_i's
411  * PHI_i's
412  * PSI_i's
413  * ALPHA_i's
414  * LALPHA_i's
415  */
416  add_to_list_of_vars(remove, get_ith_template_dummy, template_dim);
417  add_to_list_of_vars(remove, get_ith_region_dummy, array_dim);
420  add_to_list_of_vars(try_keep, get_ith_local_dummy, array_dim);
421 
422  /* Keep parameters !
423  */
424  MAP(ENTITY, e,
425  {
426  const char* s = entity_module_name(e);
427 
428  if (strcmp(s, HPFC_PACKAGE) && strcmp(s, REGIONS_MODULE_NAME))
429  keep = CONS(ENTITY, e, keep);
430  /* should try to remove only variables that can be eliminated
431  * using the preconditions. Otherwise: ph1=old, 1<=old<=2,
432  * projecting old loses the right dimension...
433  */
434  /* try_remove = CONS(ENTITY, e, try_remove); */
435  },
436  try_remove);
437 
438  /* others
439  */
440  gen_remove(&try_remove, (entity) TCST);
441  MAP(ENTITY, e, gen_remove(&try_remove, e), keep);
442  MAP(ENTITY, e, gen_remove(&try_remove, e), try_keep);
443  MAP(ENTITY, e, gen_remove(&try_remove, e), remove);
444 
445  DEBUG_ELST(7, "keep", keep);
446  DEBUG_ELST(7, "try_keep", try_keep);
447  DEBUG_ELST(7, "try_remove", try_remove);
448  DEBUG_ELST(7, "remove", remove);
449 
450  clean_the_system(&syst, &remove, &try_remove);
451 
452  DEBUG_SYST(6, entity_name(array), syst);
453 
455  gen_free_list(try_keep);
456  gen_free_list(try_remove);
457 
458  return(syst);
459 }
460 
461 /* Variables of Psysteme syst are ordered and put in different
462  * lists. Especially, deducable variables are listed, the equalities
463  * that allow to rebuild them are also listed, and they are removed
464  * from the original system by *exact* integer projection.
465  *
466  * Other variables are (should be) the parameters, the processors,
467  * and the variables to be used to scan polyhedron.
468  */
469 static void
471  Psysteme *psyst,
472  entity array,
473  list *plparam,
474  list *plproc,
475  list *plscan,
476  list *plrebuild)
477 {
478  int processor_dim = (array_distributed_p(array) ?
480  dim = -1;
481  list
482  all = base_to_list(sc_base(*psyst)),
483  lparam = NIL, lproc = NIL, lscan = NIL, lrebuild = NIL;
484 
485  gen_remove(&all, (entity) TCST); /* just in case */
486 
487  pips_debug(5, "considering %zd variables\n", gen_length(all));
488 
489  /* parameters: those variables that are not dummies...
490  */
491  MAP(ENTITY, v,
492  if (!entity_hpfc_dummy_p(v)) lparam = CONS(ENTITY, v, lparam),
493  all);
494 
495  MAP(ENTITY, e, gen_remove(&all, e), lparam);
496 
497  /* processors
498  */
499  for(dim=processor_dim; dim>=1; dim--)
500  {
501  entity
503 
504  lproc = CONS(ENTITY, dummy, lproc);
505  gen_remove(&all, dummy);
506  }
507 
508  /* scanners and deducables
509  */
510  lrebuild =
513  true)),
514  &lscan);
515 
516  /* return results
517  */
518  *plparam = lparam,
519  *plproc = lproc,
520  *plscan = lscan, /* lscan is implicitely ordered */
521  *plrebuild = lrebuild;
522 
523  gen_free_list(all);
524 
525  DEBUG_ELST(4, "params", lparam);
526  DEBUG_ELST(4, "procs", lproc);
527  DEBUG_ELST(4, "scanners", lscan);
528 
529  ifdebug(4)
530  {
532 
533  fprintf(stderr, "deducables:\n ");
534  MAP(EXPRESSION, ex,
535  {
537 
538  fprintf(stderr, "%s rebuilt with ", entity_local_name
540  egalite_fprint(stderr, pc, (string(*)(Variable))entity_local_name);
541  },
542  lrebuild);
543  }
544 
545  build_sc_nredund_2pass(psyst);
546  sc_base(*psyst) = (base_rm(sc_base(*psyst)), BASE_NULLE);
547  sc_creer_base(*psyst);
548 
549  DEBUG_SYST(4, entity_name(array), *psyst);
550 }
551 
552 /* list simplify_deducable_variables(syst, vars, pleftvars)
553  * Psysteme syst;
554  * list vars, *pleftvars;
555  *
556  * variables from entity list vars that can be rebuilt by the Psysteme
557  * syst are removed from it and stored as an expression list which is
558  * returned. The variables that are not removed are returned as another
559  * entity list, *pleftvars.
560  */
561 list /* of expression */
563  Psysteme syst,
564  list vars,
565  list *pleftvars)
566 {
567  list result = NIL;
568  *pleftvars = NIL;
569 
570  MAP(ENTITY, dummy,
571  {
573  Value coeff = VALUE_ZERO;
574 
575  if (eq = eq_v_min_coeff(sc_egalites(syst), (Variable) dummy, &coeff),
576  value_one_p(coeff))
577  {
578  result =
583  vect_dup(eq->vecteur))),
584  result);
585 
586  syst = sc_variable_substitution_with_eq_ofl_ctrl(syst, eq,
587  (Variable) dummy,
588  FWD_OFL_CTRL);
589  }
590  else
591  {
592  *pleftvars = CONS(ENTITY, dummy, *pleftvars);
593  }
594  },
595  vars);
596 
597  base_rm(sc_base(syst)), sc_base(syst) = BASE_NULLE, sc_creer_base(syst);
598 
599  return(result);
600 }
601 
602 /* output 7 entities created by creation if in list le
603  */
604 static list /* of entity */
606  list le,
607  entity (*creation)())
608 {
609  list result = NIL;
610  int i;
611 
612  for(i=7; i>=1; i--)
613  {
614  entity dummy = creation(i);
615 
616  if (gen_in_list_p(dummy, le))
617  result = CONS(ENTITY, dummy, result);
618  }
619 
620  return(result);
621 }
622 
623 /* list hpfc_order_variables(list)
624  *
625  * the input list of entities is ordered so that:
626  * PSI_i's, GAMMA_i's, DELTA_i's, IOTA_i's, ALPHA_i's, LALPHA_i's...
627  */
628 list
630  list le,
631  bool number_first)
632 {
633  list result = NIL;
634 
635  result =
636  gen_nconc(result,
638 
639  if (number_first)
640  {
641  int i;
642  list l = NIL, lr = NIL;
643 
644  for (i=7; i>0; i--)
649  l))));
650 
651  MAP(ENTITY, e,
652  {
653  if (gen_in_list_p(e, le)) lr = CONS(ENTITY, e, lr); /* reverse! */
654  },
655  l);
656 
657  gen_free_list(l);
658  result = gen_nconc(result, lr);
659  }
660  else
661  {
662  result =
663  gen_nconc(result,
665 
666  result =
667  gen_nconc(result,
669 
670  result =
671  gen_nconc(result,
673 
674  result =
675  gen_nconc(result,
677  }
678 
679  result =
680  gen_nconc(result,
682 
683  pips_assert("same length", gen_length(result)==gen_length(le));
684 
685  return(result);
686 }
687 
688 void
690  Psysteme syst,
691  list processors,
692  list scanners,
693  Psysteme *pcondition,
694  Psysteme *pproc_echelon,
695  Psysteme *ptile_echelon)
696 {
697  Pbase
698  outer = entity_list_to_base(processors),
699  inner = entity_list_to_base(scanners);
700 
701  DEBUG_SYST(8, "initial system", syst);
702 
703  algorithm_tiling(syst, outer, inner,
704  pcondition, pproc_echelon, ptile_echelon);
705 
706  DEBUG_SYST(3, "condition", *pcondition);
707  DEBUG_BASE(3, "proc vars", outer);
708  DEBUG_SYST(3, "processors", *pproc_echelon);
709  DEBUG_BASE(3, "tile vars", inner);
710  DEBUG_SYST(3, "tiles", *ptile_echelon);
711 
712  base_rm(outer);
713  base_rm(inner);
714 }
715 
716 
717 /* void hpfc_simplify_condition(psc, stat, move)
718  *
719  * remove conditions that are not usefull from *psc, i.e. that are
720  * redundent with pre/post conditions depending on when the movement is
721  * done
722  */
723 void
725  Psysteme *psc,
726  statement stat,
727  tag move)
728 {
729  Psysteme
730  pstrue = statement_context(stat, move),
731  cleared = extract_nredund_subsystem(*psc, pstrue);
732 
733  *psc = (sc_rm(*psc), cleared);
734 }
735 
736 /* generates the Psystem for IOs inside the statement stat,
737  * that use entity ent which should be a variable.
738  */
739 static Psysteme
741  entity array,
742  statement stat,
743  tag move,
744  tag act)
745 {
746  Psysteme result = SC_UNDEFINED;
747 
748  pips_assert("variable", entity_variable_p(array));
749 
751  {
752  result = generate_distributed_io_system(array, stat, move, act);
753  result = clean_distributed_io_system(result, array, move);
754  }
755  else
756  {
757  result = generate_shared_io_system(array, stat, move, act);
758  result = clean_shared_io_system(result, array, move);
759  }
760 
762 
763  DEBUG_SYST(2, concatenate("array ", entity_name(array), NULL), result);
764 
765  return result;
766 }
767 
768 static void
770  entity array,
771  statement stat,
772  tag move,
773  tag act,
774  statement *psh,
775  statement *psn)
776 {
777  Psysteme syst = generate_io_system(array, stat, move, act);
779 
780  pips_assert("variable and syst",
781  entity_variable_p(array) && syst!=SC_UNDEFINED);
782 
784  {
785  /* SCANNING: Variables must be classified as:
786  * - parameters
787  * - processors
788  * - scanner
789  * - deducable
790  */
791  Psysteme proc_echelon, tile_echelon, condition;
792  list parameters = NIL, processors = NIL, scanners = NIL, rebuild = NIL;
793 
794  /* Now we have a set of equations and inequations, and we are going
795  * to organise a scanning of the data and the communications that
796  * are needed
797  */
799  (&syst, array, &parameters, &processors, &scanners, &rebuild);
800 
801  hpfc_algorithm_tiling(syst, processors, scanners,
802  &condition, &proc_echelon, &tile_echelon);
803  hpfc_simplify_condition(&condition, stat, move);
804 
805  /* the sorting is done again at the code generation,
806  * but this phase will ensure more determinism in the debug messages
807  */
808  /* sc_vect_sort(condition, compare_Pvecteur); */
809  sc_sort(condition, sc_base(condition), compare_Pvecteur);
810  sc_vect_sort(proc_echelon, compare_Pvecteur);
811  sc_vect_sort(tile_echelon, compare_Pvecteur);
812 
813  if (!sc_empty_p(proc_echelon) && !sc_empty_p(tile_echelon))
814  {
816  (array, move,
817  condition, proc_echelon, tile_echelon,
818  parameters, processors, scanners, rebuild,
819  psh, psn);
820  }
821  else
822  {
823  hpfc_warning("empty io for %s\n", entity_name(array));
826  }
827  }
828  else /* array not distributed */
829  {
830  Psysteme row_echelon = SC_UNDEFINED, condition = SC_UNDEFINED;
831  list tmp = NIL, parameters = NIL, scanners = NIL, rebuild = NIL;
832 
833  pips_assert("update", movement_update_p(move));
834 
836  (&syst, array, &parameters, &tmp, &scanners, &rebuild);
837 
838  pips_assert("empty list", ENDP(tmp));
839 
840  hpfc_algorithm_row_echelon(syst, scanners, &condition, &row_echelon);
841  hpfc_simplify_condition(&condition, stat, move);
842 
843  /* the sorting is done again at the code generation,
844  * but this phase will ensure more determinism in the debug messages
845  */
846  /* sc_vect_sort(condition, compare_Pvecteur); */
847  sc_sort(condition, sc_base(condition), compare_Pvecteur);
848  sc_vect_sort(row_echelon, compare_Pvecteur);
849 
850  if (!sc_empty_p(row_echelon))
851  {
853  (array, move,
854  condition, row_echelon,
855  parameters, scanners, rebuild,
856  psh, psn);
857  }
858  else
859  {
860  hpfc_warning("empty io for %s\n", entity_name(array));
863  }
864  }
865 
867 
868  DEBUG_STAT(8, "Host", *psh);
869  DEBUG_STAT(8, "Node", *psn);
870 }
871 
872 /* add a local declaration for entity array on the host.
873  * if entity array is dynamic, then declaration based on the primary.
874  */
875 static void
877  entity array)
878 {
879  entity primary, host_array;
880  storage s;
881 
882  if (dynamic_entity_p(array))
883  {
884  primary = load_primary_entity(array);
885  if (bound_new_host_p(primary)) /* already exists, just add the link */
886  {
888  return;
889  }
890  }
891  else
892  primary = array;
893 
894  /* create the host entity
895  */
896  host_array = AddEntityToModule(primary, host_module);
897  store_new_host_variable(host_array, primary);
898 
899  if (primary!=array) /* second link if needed */
900  store_new_host_variable(host_array, array);
901 
902  /* local, not passed as an argument
903  */
904  s = entity_storage(host_array);
905  if (storage_formal_p(s))
906  formal_offset(storage_formal(s)) = INT_MAX;
907 }
908 
909 /* compile an io statement
910  */
912  statement stat, /* statement to compile */
913  statement *hp, /* returned Host code */
914  statement *np) /* returned Node code */
915 {
916  list
917  /* of effect */ entities = load_rw_effects_list(stat),
918  lh_collect = NIL, lh_io = NIL, lh_update = NIL,
919  ln_collect = NIL, ln_io = NIL, ln_update = NIL;
920  statement sh, sn;
921 
922  debug_on("HPFC_IO_DEBUG_LEVEL");
923  pips_debug(1, "compiling!\n");
924  pips_debug(2, "statement %" _intFMT " (%p), %zd arrays\n",
925  statement_number(stat), stat, gen_length(entities));
926 
927  // quicker for continue and so...
928  if (empty_code_p(stat))
929  {
930  pips_debug(3, "empty statement\n");
931  *hp = copy_statement(stat);
932  *np = copy_statement(stat);
933  debug_off();
934  return;
935  }
936 
937  // for each effect e on that statement
938  FOREACH(effect, e, entities)
939  {
941  pips_debug(3, "variable %s\n", entity_name(array));
942 
943  if (io_effect_entity_p(array)) // skip LUNS
944  continue;
945 
946  action act = effect_action(e);
948 
949  pips_assert("avoid replicated array I/O", /* not implemented */
951 
952  if ((!array_distributed_p(array)) && action_read_p(act))
953  {
954  pips_debug(7, "skipping array %s movements - none needed\n",
955  entity_name(array));
956  continue;
957  }
958 
959  // add array declaration on host if necessary
962 
963  // collect data if necessary
964  if (array_distributed_p(array) &&
966  (action_read_p(act) ||
967  (action_write_p(act) &&
968  approximation_may_p(apr) &&
969  !get_bool_property("HPFC_IGNORE_MAY_IN_IO"))))
970  {
972  action_tag(act), &sh, &sn);
973  lh_collect = CONS(STATEMENT, sh, lh_collect);
974  ln_collect = CONS(STATEMENT, sn, ln_collect);
975  }
976 
977  // update data if necessary
978  // action = write and data may be used later (out regions)
980  {
982  action_tag(act), &sh, &sn);
983  lh_update = CONS(STATEMENT, sh, lh_update);
984  ln_update = CONS(STATEMENT, sn, ln_update);
985  }
986  }
987 
988  lh_io = CONS(STATEMENT, copy_statement(stat), NIL);
989 
990  if (get_bool_property("HPFC_SYNCHRONIZE_IO"))
991  {
992  // could do it only for write statements
994 
995  lh_io = CONS(STATEMENT, hpfc_make_call_statement(synchro, NIL), lh_io);
996  ln_io = CONS(STATEMENT, hpfc_make_call_statement(synchro, NIL), ln_io);
997  }
998 
999  *hp = make_block_statement(gen_nconc(lh_collect,
1000  gen_nconc(lh_io,
1001  lh_update)));
1002  *np = make_block_statement(gen_nconc(ln_collect,
1003  gen_nconc(ln_io,
1004  ln_update)));
1005 
1006  DEBUG_STAT(9, "Host", *hp);
1007  DEBUG_STAT(9, "Node", *np);
1008 
1009  debug_off();
1010 }
1011 
1012 /* that is all
1013  */
normalized make_normalized(enum normalized_utype tag, void *val)
Definition: ri.c:1447
expression make_expression(syntax a1, normalized a2)
Definition: ri.c:886
statement copy_statement(statement p)
STATEMENT.
Definition: ri.c:2186
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
syntax make_syntax(enum syntax_utype tag, void *val)
Definition: ri.c:2491
static entity current_entity
Definition: alias_check.c:513
#define VALUE_ZERO
#define value_one_p(val)
#define VALUE_MONE
int Value
#define VALUE_ONE
bdt base
Current expression.
Definition: bdt_read_paf.c:100
bool entity_hpfc_dummy_p(entity e)
Variables.
Definition: build-system.c:106
Psysteme entity_to_declaration_constraints(entity e, tag what)
gives back the constraints due to the declarations.
Definition: build-system.c:285
Psysteme hpfc_compute_unicity_constraints(entity e)
Psysteme hpfc_compute_unicity_constraints(e) entity e should be an array;.
Definition: build-system.c:360
Psysteme generate_system_for_distributed_variable(entity v)
Psysteme generate_system_for_variable(v) entity v;.
Definition: build-system.c:789
effect entity_to_region(statement stat, entity ent, tag act)
effect entity_to_region(stat, ent, act) statement stat; entity ent; tag act;
Definition: build-system.c:515
Psysteme hpfc_unstutter_dummies(entity array)
Definition: build-system.c:767
entity host_module
HPFC - Fabien Coelho, May 1993 and later...
Definition: compiler.c:47
int compare_Pvecteur(Pvecteur *pv1, Pvecteur *pv2)
comparison function for Pvecteur in pips, to be used by qsort.
Definition: constraint.c:50
#define CONTRAINTE_UNDEFINED
Pcontrainte contrainte_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
Pcontrainte contrainte_var_min_coeff(Pcontrainte, Variable, Value *, bool)
Pcontrainte contrainte_var_min_coeff(Pcontrainte contraintes, Variable v, int *coeff) input : a list ...
Definition: unaires.c:345
void egalite_fprint(FILE *, Pcontrainte, char *(*)(Variable))
void reset_information_for_code_optimizations(void)
void set_information_for_code_optimizations(Psysteme)
I could keep the system for further optimizations...
int dummy
A dummy file, to prevent empty libraries from breaking builds.
Definition: dummy.c:41
bool(* dynamic_entity_p)(entity)
as expected, true if entity e is dynamic.
Definition: dynamic.c:145
#define region
simulation of the type region
void print_regions(list)
list load_out_effects_list(statement)
list load_in_effects_list(statement)
list load_rw_effects_list(statement)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define effect_system(e)
#define effect_variable(e)
For COMPATIBILITY purpose only - DO NOT USE anymore.
bool io_effect_entity_p(entity)
Definition: effects.c:496
#define effect_action(x)
Definition: effects.h:642
#define approximation_may_p(x)
Definition: effects.h:363
#define action_write_p(x)
Definition: effects.h:314
#define action_tag(x)
Definition: effects.h:310
#define action_read_p(x)
Definition: effects.h:311
#define effect_approximation(x)
Definition: effects.h:644
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
statement make_block_statement(list)
Make a block statement from a list of statement.
Definition: statement.c:616
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
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
size_t gen_length(const list l)
Definition: list.c:150
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
bool gen_in_list_p(const void *vo, const list lx)
tell whether vo belongs to lx
Definition: list.c:734
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
bool empty_code_p(statement)
statement.c
Definition: statement.c:86
statement make_continue_statement(entity)
Definition: statement.c:953
void store_new_host_variable(entity new, entity old)
#define HPFC_PACKAGE
local definitions
Definition: hpfc-local.h:27
bool replicated_p(entity e)
replicated_p
Definition: hpfc-util.c:96
#define array_to_template(array)
#define DEBUG_SYST(D, W, S)
#define array_to_processors(array)
#define DEBUG_BASE(D, W, B)
#define DEBUG_ELST(D, W, L)
#define template_to_processors(template)
#define SYNCHRO
#define is_movement_update
#define hpfc_warning
WARNING.
#define DEBUG_STAT(D, W, S)
#define movement_update_p(t)
#define is_movement_collect
Efficient I/O tags.
#define add_to_list_of_vars(l, fun, n)
list of variables...
Definition: defines-local.h:89
list base_to_list(Pbase base)
Most includes are centralized here.
#define movement_collect_p(t)
void generate_io_statements_for_distributed_arrays(entity, tag, Psysteme, Psysteme, Psysteme, list, list, list, list, statement *, statement *)
bool bound_new_host_p(entity)
entity hpfc_name_to_entity(const char *)
Definition: run-time.c:817
entity get_ith_template_dummy(int)
entity get_ith_cycle_dummy(int)
void generate_io_statements_for_shared_arrays(entity, tag, Psysteme, Psysteme, list, list, list, statement *, statement *)
entity get_ith_region_dummy(int)
entity get_ith_array_dummy(int)
entity get_ith_shift_dummy(int)
entity load_primary_entity(entity)
entity get_ith_block_dummy(int)
statement hpfc_make_call_statement(entity, list)
statement hpfc_make_call_statement(e, l) generate a call statement to function e, with expression lis...
Definition: run-time.c:318
entity get_ith_processor_dummy(int)
entity get_ith_local_dummy(int)
entity load_new_host(entity)
bool array_distributed_p(entity)
static void put_variables_in_ordered_lists(Psysteme *psyst, entity array, list *plparam, list *plproc, list *plscan, list *plrebuild)
Variables of Psysteme syst are ordered and put in different lists.
Definition: io-compile.c:470
void hpfc_simplify_condition(Psysteme *psc, statement stat, tag move)
void hpfc_simplify_condition(psc, stat, move)
Definition: io-compile.c:724
void clean_the_system(Psysteme *ps, list *plrm, list *pltry)
Definition: io-compile.c:360
list make_list_of_dummy_variables(entity(*creation)(), int number)
of entity
Definition: io-compile.c:143
static Psysteme generate_distributed_io_system(entity array, statement stat, tag move, tag act)
Definition: io-compile.c:197
static Psysteme clean_shared_io_system(Psysteme syst, entity array, tag move)
Definition: io-compile.c:285
static bool current_entity_is_updated_before_p(statement stat, entity current_entity)
IN Regions(effects) are used to verify if the entity current_entity is initialized before it's used i...
Definition: io-compile.c:84
void io_efficient_compile(statement stat, statement *hp, statement *np)
compile an io statement
Definition: io-compile.c:911
static Psysteme statement_context(statement stat, tag move)
Definition: io-compile.c:116
static void add_declaration_to_host_and_link(entity array)
add a local declaration for entity array on the host.
Definition: io-compile.c:876
list hpfc_order_variables(list le, bool number_first)
list hpfc_order_variables(list)
Definition: io-compile.c:629
void hpfc_algorithm_row_echelon(Psysteme syst, list scanners, Psysteme *pcond, Psysteme *penum)
io-compile.c
Definition: io-compile.c:127
static list hpfc_order_specific_variables(list le, entity(*creation)())
output 7 entities created by creation if in list le
Definition: io-compile.c:605
static Psysteme generate_shared_io_system(entity array, statement stat, tag move, tag act)
Definition: io-compile.c:156
void hpfc_algorithm_tiling(Psysteme syst, list processors, list scanners, Psysteme *pcondition, Psysteme *pproc_echelon, Psysteme *ptile_echelon)
Definition: io-compile.c:689
void remove_variables_from_system(Psysteme *ps, list *plv)
Definition: io-compile.c:345
static bool current_entity_is_used_later_p(statement stat, entity current_entity)
HPFC module by Fabien COELHO.
Definition: io-compile.c:47
static Psysteme clean_distributed_io_system(Psysteme syst, entity array, tag move)
collect or update
Definition: io-compile.c:373
static Psysteme generate_io_system(entity array, statement stat, tag move, tag act)
generates the Psystem for IOs inside the statement stat, that use entity ent which should be a variab...
Definition: io-compile.c:740
static void generate_io_collect_or_update(entity array, statement stat, tag move, tag act, statement *psh, statement *psn)
Definition: io-compile.c:769
list simplify_deducable_variables(Psysteme syst, list vars, list *pleftvars)
list simplify_deducable_variables(syst, vars, pleftvars) Psysteme syst; list vars,...
Definition: io-compile.c:562
void remove_variables_if_possible(Psysteme *psyst, list *plvars)
Definition: io-compile.c:245
#define debug_on(env)
Definition: misc-local.h:157
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define debug_off()
Definition: misc-local.h:160
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
int tag
TAG.
Definition: newgen_types.h:92
#define _intFMT
Definition: newgen_types.h:57
#define REGIONS_MODULE_NAME
Already defined.
#define entity_variable_p(e)
An entity_variable_p(e) may hide a typedef and hence a functional type.
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
entity AddEntityToModule(entity e, entity module)
!!! caution, it may not be a module, but a common...
Definition: entity.c:3171
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
Pbase entity_list_to_base(list l)
Definition: entity.c:2860
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
int NumberOfDimension(entity)
Definition: size.c:588
#define formal_offset(x)
Definition: ri.h:1408
#define storage_formal_p(x)
Definition: ri.h:2522
#define reference_variable(x)
Definition: ri.h:2326
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define entity_storage(x)
Definition: ri.h:2794
@ is_syntax_reference
Definition: ri.h:2691
#define storage_formal(x)
Definition: ri.h:2524
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define entity_undefined
Definition: ri.h:2761
#define entity_name(x)
Definition: ri.h:2790
#define transformer_relation(x)
Definition: ri.h:2873
#define expression_normalized(x)
Definition: ri.h:1249
#define statement_number(x)
Definition: ri.h:2452
#define normalized_linear(x)
Definition: ri.h:1781
#define predicate_system(x)
Definition: ri.h:2069
@ is_normalized_linear
Definition: ri.h:1760
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
Psysteme sc_rn(Pbase b)
Psysteme sc_rn(Pbase b): build a Psysteme without constraints to define R^n, where n is b's dimension...
Definition: sc_alloc.c:336
void sc_creer_base(Psysteme ps)
void sc_creer_base(Psysteme ps): initialisation des parametres dimension et base d'un systeme lineair...
Definition: sc_alloc.c:129
void sc_rm(Psysteme ps)
void sc_rm(Psysteme ps): liberation de l'espace memoire occupe par le systeme de contraintes ps;
Definition: sc_alloc.c:277
bool sc_empty_p(Psysteme sc)
bool sc_empty_p(Psysteme sc): check if the set associated to sc is the constant sc_empty or not.
Definition: sc_alloc.c:350
void build_sc_nredund_2pass(Psysteme volatile *psc)
void build_sc_nredund_2pass Psysteme *psc;
Psysteme extract_nredund_subsystem(Psysteme s1, Psysteme s2)
Psysteme extract_nredund_subsystem(s1, s2) Psysteme s1, s2;.
Pcontrainte eq
element du vecteur colonne du systeme donne par l'analyse
Definition: sc_gram.c:108
Psysteme sc_append(Psysteme s1, Psysteme s2)
Psysteme sc_append(Psysteme s1, Psysteme s2): calcul de l'intersection des polyedres definis par s1 e...
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
void algorithm_tiling(Psysteme syst, Pbase outer, Pbase inner, Psysteme *pcondition, Psysteme *ptile_enum, Psysteme *piter_enum)
void algorithm_row_echelon_generic(Psysteme scn, Pbase base_index, Psysteme *pcondition, Psysteme *penumeration, bool redundancy)
each variable should be at least within one <= and one >=; scn IS NOT modified.
void sc_find_equalities(Psysteme *ps)
void sc_vect_sort(Psysteme s, int(*compare)(Pvecteur *, Pvecteur *))
the name is self explanatory, I guess.
Definition: sc_unaires.c:116
void sc_sort(Psysteme sc, Pbase sort_base, int(*compare)(Pvecteur *, Pvecteur *))
SORT a Psysteme according to sort_base and compare (given to qsort).
Definition: sc_unaires.c:137
transformer load_statement_precondition(statement)
transformer load_statement_postcondition(statement)
#define ifdebug(n)
Definition: sg.c:47
static entity array
Pvecteur vecteur
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
@ keep
bj > b1 -> h1/hj = h1
Definition: union-local.h:61
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define VECTEUR_NUL
DEFINITION DU VECTEUR NUL.
#define NO_OFL_CTRL
#define base_rm(b)
void * Variable
arithmetique is a requirement for vecteur, but I do not want to inforce it in all pips files....
Definition: vecteur-local.h:60
#define FWD_OFL_CTRL
#define BASE_NULLE
MACROS SUR LES BASES.
Pvecteur vect_dup(Pvecteur v_in)
Pvecteur vect_dup(Pvecteur v_in): duplication du vecteur v_in; allocation de et copie dans v_out;.
Definition: alloc.c:51
Pvecteur vect_new(Variable var, Value coeff)
Pvecteur vect_new(Variable var,Value coeff): allocation d'un vecteur colineaire au vecteur de base va...
Definition: alloc.c:110
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78