PIPS
dynamic.c
Go to the documentation of this file.
1 /*
2 
3  $Id: dynamic.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  * This file provides functions used by directives.c to deal with
30  * dynamic mappings (re*). It includes keeping track of variables
31  * tagged as dynamic, and managing the static synonyms introduced
32  * to deal with them in HPFC.
33  */
34 
35 #include "defines-local.h"
36 
37 #include "control.h"
38 #include "effects-generic.h"
39 #include "effects-simple.h"
40 #include "effects-convex.h"
41 
42 /* DYNAMIC MANAGEMENT
43  *
44  * the synonyms of a given array are stored in a entities.
45  * What I intend as a synonym is a version of the array or template
46  * which is distributed or aligned in a different way.
47  * the renamings are associated to the remapping statements here.
48  * - dynamic_hpf: keeps track of entities declared as dynamic.
49  * - primary_entity: primary entity of an entity, when synonyms are
50  * introduced to handle remappings.
51  * - renamings: remappings associated to a statement.
52  * - maybeuseful_mappings: to be kept for a statement.
53  * - similar_mapping: copies with similar mappings...
54  */
56 GENERIC_GLOBAL_FUNCTION(primary_entity, entitymap)
58 GENERIC_GLOBAL_FUNCTION(maybeuseful_mappings, statement_entities)
59 GENERIC_GLOBAL_FUNCTION(similar_mapping, entitymap)
60 
62 {
63  if (!bound_dynamic_hpf_p(e))
64  pips_user_error("%s is not dynamic\n", entity_local_name(e));
65 
66  return load_primary_entity(e);
67 }
68 
69 bool
71 {
74  else
75  return false;
76 }
77 
78 
79 /* DYNAMIC STATUS management.
80  */
82 {
88 }
89 
91 {
96  /* reset_similar_mapping(); */
97 }
98 
100 {
103  get_renamings(),
105  /* get_similar_mapping() */
106 }
107 
109 {
114  /* set_similar_mapping(...) */
115 }
116 
118 {
121  close_renamings();
124 }
125 
126 /* a new dynamic entity is stored.
127  * HPF allows arrays and templates as dynamic.
128  * ??? could be asserted, but not here. should be checked afterward.
129  */
131 {
132  if (!bound_dynamic_hpf_p(e))
133  {
135  store_primary_entity(e, e);
136 
137  store_similar_mapping(e, e);
138  }
139  /* else the entity was already declared as dynamic... */
140 }
141 
142 /* as expected, true if entity e is dynamic.
143  * it is just a function name nicer than bound_...
144  */
146 
147 /* what: new_e is stored as a synonym of e.
148  */
150  entity new_e,
151  entity e)
152 {
153  entities es = load_dynamic_hpf(e);
154  pips_debug(3, "%s as %s synonyms\n", entity_name(new_e), entity_name(e));
155  pips_assert("dynamicity", dynamic_entity_p(e) && !dynamic_entity_p(new_e));
156  entities_list(es) = CONS(ENTITY, new_e, entities_list(es));
157  store_dynamic_hpf(new_e, es);
159 }
160 
161 void
163 {
164  /* ??? for final update after compilation! hummm....
165  */
166 
167  MAP(ENTITY, array,
168  {
169  pips_debug(7, "considering array %s\n", entity_name(array));
170 
171  /* ??? should not deal with the same array twice...
172  */
173  if (dynamic_entity_p(array) &&
175  bound_new_node_p(array)) /* may be in another module */
176  {
179  entity ns = load_new_node(s);
180 
181  pips_debug(7, "array %s\n", entity_name(array));
182 
183  if (!bound_new_node_p(n)) {
186  }
187  }
188  },
190 }
191 
192 /******************************** NEW ENTITIES FOR MANAGING DYNAMIC ARRAYS */
193 
194 /* builds a synonym for entity e. The name is based on e, plus
195  * an underscore and a number added. May be used for templates and arrays.
196  * the new synonym is added as a synonym of e.
197  */
199 {
200  int n = gen_length(entities_list(load_dynamic_hpf(e))); /* syn. number */
201  entity primary = load_primary_entity(e), new_e;
202  const char* module = entity_module_name(e);
203  char new_name[100];
204 
205  sprintf(new_name, "%s_%x", entity_local_name(primary), (unsigned int) n);
206 
207  pips_debug(5, "building entity %s\n", new_name);
208 
209  new_e = FindOrCreateEntityLikeModel(module, new_name, primary);
210 
211  if (storage_formal_p(entity_storage(new_e)))
212  { /* the new entity is rather local! */
213  storage s = entity_storage(new_e);
215  entity_storage(new_e) =
217  make_ram(sub,
220  free_storage(s);
221  }
222 
224 
225  add_dynamic_synonym(new_e, e);
226  return new_e;
227 }
228 
229 static void
231  entity a, /* array a to be compared against its similars */
232  list /* of entity */ others)
233 {
234  bool similar_found = false;
235 
236  pips_debug(3, "of %s\n", entity_name(a));
237 
238  if (!array_distributed_p(a)) /* no templates! */
239  return;
240 
241  if (bound_similar_mapping_p(a)) /* job already done */
242  return;
243 
244  /* look for copies with similar mappings for latter update
245  */
246  MAP(ENTITY, e,
247  {
248  pips_debug(7, "%s against %s\n", entity_name(a), entity_name(e));
249  if (a!=e && array_distribution_similar_p(e, a))
250  {
251  /* a -> init[e] for storage purposes
252  */
253  pips_debug(8, "found similar: %s -> %s\n",
254  entity_name(a), entity_name(e));
256  similar_found = true;
257  break;
258  }
259  },
260  others);
261 
262  if (!similar_found) store_similar_mapping(a, a);
263 
264  return;
265 }
266 
267 /* check all *dynamic* arrays for some similars...
268  */
269 void hpfc_check_for_similarities(list /* of entity */ le)
270 {
271  MAP(ENTITY, array,
272  {
274  {
275  list /* of entity */
276  seens = CONS(ENTITY, array, NIL); /* similar bases */
277 
278  pips_assert("is a primary!", primary_entity_p(array));
279 
281 
282  MAP(ENTITY, a,
283  {
284  if (!gen_in_list_p(a, seens))
285  {
286  entity similar;
287  check_for_similarity(a, seens);
288  similar = load_similar_mapping(a);
289  pips_debug(1, "%s similar to %s\n",
290  entity_name(a), entity_name(similar));
291 
292  seens = gen_once(similar, seens);
293  }
294  },
296 
297  gen_free_list(seens);
298  }
299  },
300  le);
301 }
302 
303 /* builds a new synonym for array a, the alignment of which
304  * will be al. The new array is set as distributed.
305  */
307  entity a,
308  align al)
309 {
310  entity new_a = new_synonym(a);
312  store_hpf_alignment(new_a, al);
313  return new_a;
314 }
315 
316 /* builds a new synonym for template t, the distribution of which
317  * will be di. the new entity is set as a template, and/or as an array
318  */
320  entity t,
321  distribute di)
322 {
323  entity new_t = new_synonym(t);
324  set_template(new_t);
325  store_hpf_distribution(new_t, di);
326  return new_t;
327 }
328 
330  entity e1,
331  entity e2)
332 {
333  int ndim;
334  if (e1==e2) return true;
335 
336  ndim = NumberOfDimension(e1);
337 
338  if (ndim!=NumberOfDimension(e2)) return false;
339 
340  for (; ndim>0; ndim--)
341  {
342  int l1, u1, l2, u2;
343  get_entity_dimensions(e1, ndim, &l1, &u1);
344  get_entity_dimensions(e2, ndim, &l2, &u2);
345  if (l1!=l2 || u1!=u2) return false;
346  }
347 
348  return true;
349 }
350 
351 /* comparison of DISTRIBUTE.
352  */
353 static bool same_distribute_p(
354  distribute d1,
355  distribute d2)
356 {
357  list /* of distributions */ l1 = distribute_distribution(d1),
358  l2 = distribute_distribution(d2);
359 
361  distribute_processors(d2))) return false;
362 
363  pips_assert("valid distribution", gen_length(l1)==gen_length(l2));
364 
365  for(; !ENDP(l1); POP(l1), POP(l2))
366  {
367  distribution i1 = DISTRIBUTION(CAR(l1)),
368  i2 = DISTRIBUTION(CAR(l2));
370  s2 = distribution_style(i2);
371  tag t1 = style_tag(s1);
372 
373  if (t1!= (tag) style_tag(s2)) return false;
374  if (t1!=is_style_none &&
377  return false;
378  }
379 
380  return true;
381 }
382 
383 /* comparison of ALIGN.
384  */
386  alignment a,
387  list /* of alignments */ l)
388 {
389  intptr_t adim = alignment_arraydim(a),
390  tdim = alignment_templatedim(a);
391 
392  MAP(ALIGNMENT, b,
393  {
394  if (adim==alignment_arraydim(b) && tdim==alignment_templatedim(b))
396  alignment_rate(b)) &&
398  alignment_constant(b));
399  },
400  l);
401 
402  return false;
403 }
404 
406  entity t1,
407  entity t2)
408 {
409  if (t1==t2)
410  return true;
411  else if (!conformant_entities_p(t1, t2))
412  return false;
413  else
414  return same_distribute_p
416 }
417 
418 static bool same_align_p(
419  align a1,
420  align a2)
421 {
422  list /* of alignments */ l1 = align_alignment(a1),
423  l2 = align_alignment(a2);
424 
426  (gen_length(l1)!=gen_length(l2)))
427  return false;
428 
429  MAP(ALIGNMENT, a,
430  if (!same_alignment_in_list_p(a, l2)) return false,
431  l1);
432 
433  return true;
434 }
435 
436 /* entity array_synonym_aligned_as(array, a)
437  * entity array;
438  * align a;
439  *
440  * what: finds or creates a new entity aligned as needed.
441  * input: an array (which *must* be dynamic) and an align
442  * output: returns an array aligned as specified by align a
443  * side effects:
444  * - creates a new entity if necessary.
445  * - this entity is stored as a synonym of array, and tagged as dynamic.
446  * - the align is freed if not used.
447  * bugs or features:
448  */
450  entity array,
451  align a)
452 {
453  ifdebug(8)
454  {
455  pips_debug(8, "array %s\n", entity_name(array));
456  print_align(a);
457  }
458 
459  MAP(ENTITY, ar,
460  {
461  if (same_align_p(load_hpf_alignment(ar), a))
462  {
463  free_align(a);
464  return ar; /* the one found is returned */
465  }
466  },
468 
469  /* else no compatible array does exist, so one must be created
470  */
471  return new_synonym_array(array, a);
472 }
473 
475  align a,
476  entity t)
477 {
478  align b = copy_align(a);
479  align_template(b) = t;
480  return b;
481 }
482 
483 /* what: finds or creates a new entity distributed as needed.
484  * input: an template (which *must* be dynamic) and a distribute
485  * output: returns a template distributed as specified by d
486  * side effects:
487  * - creates a new entity if necessary.
488  * - this entity is stored as a synonym of array, and tagged as dynamic.
489  * - the distribute is freed if not used.
490  */
492  entity temp,
493  distribute d)
494 {
495  MAP(ENTITY, t,
496  {
498  {
499  free_distribute(d);
500  return t; /* the one found is returned */
501  }
502  },
504 
505  /* else no compatible template does exist, so one must be created
506  */
507  return new_synonym_template(temp, d);
508 }
509 
510 /******************************************************** SIMILAR MAPPPINGS */
511 /* array_distribution_similar_p
512  *
513  * returns whether a1 and a2 are similar, i.e. even if
514  * distributed differently, the resulting mapping is similar.
515  *
516  * e.g. align a1(i,j) with T(i,j), distribute T(*,block)
517  * and align a2(i,j) with T(j,i), distribute T(block,*)
518  *
519  * impact: the same area can be used for holding both array versions
520  * but the version number must be accurate.
521  */
522 static bool
524 {
525  return
529 }
530 
531 #define RETAL(msg, res) \
532  { pips_debug(7, "%d because %s\n", res, msg); return res;}
533 
534 static bool
536  entity e2, entity t2, alignment a2)
537 {
538  int b1, l1, b2, l2;
539  bool b;
540 
542  {
544  RETAL("some undefined", b);
545  }
546 
547  pips_debug(7, "considering %s[dim=%"PRIdPTR"] and %s[dim=%"PRIdPTR"]\n",
550 
551  /* compares the alignments if any
552  */
554  RETAL("diff. array dim", false);
555 
557  RETAL("different rate", false);
558 
561  RETAL("different template size", false);
562 
569 
570  b=(b1-l1)==(b2-l2);
571  RETAL("shift", b);
572 }
573 
574 #define RET(msg, what) \
575  { pips_debug(6, "not similar because %s\n", msg); return what;}
576 
577 bool
579 {
580  align
581  al1 = load_hpf_alignment(a1),
582  al2 = load_hpf_alignment(a2);
583  entity
584  t1 = align_template(al1),
585  t2 = align_template(al2);
586  distribute
587  d1 = load_hpf_distribution(t1),
588  d2 = load_hpf_distribution(t2);
589  entity
590  p1 = distribute_processors(d1),
591  p2 = distribute_processors(d2);
592  int i, td1, td2,
593  ndimdist = NumberOfDimension(p1);
594 
595  pips_assert("same primary",
597 
598  pips_debug(6, "comparing %s and %s\n", entity_name(a1), entity_name(a2));
599 
600  /* conformant processors
601  * ??? could assume that P(1:1,1:n) is conformant to P'(1:n)?
602  */
603  if (!conformant_entities_p(p1, p2))
604  RET("different processors", false);
605 
606  for (i=1; i<=ndimdist; i++) /* considering ith dim of proc */
607  {
608  /* conformant distributions
609  */
610  distribution
612  (distribute_distribution(d1), i, &td1),
614  (distribute_distribution(d2), i, &td2);
615  alignment at1, at2;
616  int dsize = SizeOfIthDimension(p1,i);
617 
618  /* if the size is 1, whatever the distribution it is ok! */
619  if (dsize!=1)
620  {
621  if (!same_distribution_p(x1, x2))
622  RET("different distribution", false);
623 
624  /* conformant alignments for that pe dim
625  * !!! the HPF mapping "semantics" insure that the corresponding
626  * dimension is distributed!
627  */
630 
631  if (!same_alignment_p(a1,t1,at1,a2,t2,at2))
632  RET("different alignment", false);
633  }
634  }
635 
636  pips_debug(6, "similar distributions!\n");
637  return true;
638 }
639 
640 /**************************************************** MAPPING OF ARGUMENTS */
641 
642 /* whether call c inplies a distributed argument
643  */
644 bool
646 {
647  entity f = call_function(c);
648  int len = gen_length(call_arguments(c));
649 
650  /* no intrinsics */
652  hpf_directive_entity_p(f)) return false;
653 
654  /* else checks for distributed arguments */
655  for (; len>0; len--)
656  {
657  entity arg = find_ith_parameter(f, len);
658  if (array_distributed_p(arg)) return true;
659  }
660 
661  return false;
662 }
663 
664 static list /* of renaming */
666  list /* of renaming */ l,
667  entity o,
668  entity n)
669 {
670  MAP(RENAMING, r,
671  {
672  if (renaming_old(r)==o)
673  {
674  pips_assert("same required mapping", renaming_new(r)==n);
675  return l;
676  }
677  },
678  l);
679 
680  return CONS(RENAMING, make_renaming(o, n), l);
681 }
682 
683 /* ??? only simple calls are handled. imbrication may cause problems.
684  * ??? should recurse thru all the calls at a call instruction...
685  */
686 void
688  statement s, /* the statement the call belongs to */
689  call c) /* the call. (not necessarily an instruction) */
690 {
691  list /* of remapping */ lr = NIL,
692  /* of expression */ args;
693  int len, i;
694  entity f;
695 
696  f = call_function(c);
697  args = call_arguments(c);
698  len = gen_length(args);
699 
700  pips_debug(1, "function %s\n", entity_name(f));
701 
702  for (i=1; i<=len; i++, POP(args))
703  {
704  entity arg = find_ith_parameter(f, i);
705  pips_debug(7, "considering argument %d\n", i);
706 
707  if (array_distributed_p(arg))
708  {
709  align al;
710  entity passed, copy;
711  expression e = EXPRESSION(CAR(args));
712 
713  passed = expression_to_entity(e);
714 
715  pips_debug(8, "passed:%s, arg:%s\n",
716  entity_name(passed), entity_name(arg));
717  pips_assert("distributed and conformant",
718  array_distributed_p(passed) &&
719  conformant_entities_p(passed, arg));
720 
721  set_entity_as_dynamic(passed);
722  add_a_dynamic(passed);
723 
724  al = copy_align(load_hpf_alignment(arg));
725  copy = array_synonym_aligned_as(passed, al);
726 
727  pips_debug(3, "%s (arg %d) %s -> %s\n", entity_name(arg), i,
728  entity_name(passed), entity_name(copy));
729 
730  /* the substitution in the call will be performed at the
731  * propagation phase of dynamic arrays, later on.
732  */
733  /* add the renaming in the list.
734  * ??? should be added only once! what about call(A,A)...
735  */
736  lr = add_once_to_renaming_list(lr, passed, copy);
737  }
738  }
739 
740  if (lr) /* should always be the case */
741  {
742  list /* of statement */ lpre = NIL, lpos = NIL;
744 
745  lpre = CONS(STATEMENT,
747  NIL);
748 
749  MAP(RENAMING, r,
750  {
751  entity passed = renaming_old(r);
752  entity copied = renaming_new(r);
753 
754  lpre = CONS(STATEMENT, call_to_statement(make_call(rename,
756  CONS(EXPRESSION, entity_to_expression(copied), NIL)))),
757  lpre);
758 
759  lpos = CONS(STATEMENT, call_to_statement(make_call(rename,
761  CONS(EXPRESSION, entity_to_expression(passed), NIL)))),
762  lpos);
763  },
764  lr);
765 
767  make_instruction_block(gen_nconc(lpre, lpos));
768  /* Do not forget to move forbidden information associated with
769  block: */
771 
772  DEBUG_STAT(3, "out", s);
773  }
774 }
775 
776 
777 /* DYNAMIC LOCAL DATA
778  *
779  * these static functions are used to store the remapping graph
780  * while it is built, or when optimizations are performed on it.
781  *
782  * - alive_synonym: used when building the remapping graph. synonym of
783  * a primary entity that has reached a given remapping statement. Used
784  * for both arrays and templates.
785  * - used_dynamics: from a remapping statement, the remapped arrays that
786  * are actually referenced in their new shape.
787  * - modified_dynamics: from a remapping statement, the remapped arrays
788  * that may be modified in their new shape.
789  * - remapping_graph: the remapping graph, based on the control domain.
790  * the control_statement is the remapping statement in the code.
791  * predecessors and successors are the possible remapping statements
792  * for the arrays remapped at that vertex.
793  * - reaching_mappings: the mappings that may reached a vertex.
794  * - leaving_mappings: the mappings that may leave the vertex.
795  * (simplification assumption: only one per array)
796  * - remapped: the (primary) arrays remapped at the vertex.
797  */
800 GENERIC_LOCAL_FUNCTION(modified_dynamics, statement_entities)
801 GENERIC_LOCAL_FUNCTION(remapping_graph, controlmap)
802 GENERIC_LOCAL_FUNCTION(reaching_mappings, statement_entities)
805 
807 {
808  init_alive_synonym();
809  init_used_dynamics();
810  init_modified_dynamics();
811  init_reaching_mappings();
812  init_leaving_mappings();
813  init_remapped();
814  init_remapping_graph();
815 }
816 
818 {
819  close_alive_synonym();
820  close_used_dynamics();
821  close_modified_dynamics();
822  close_reaching_mappings();
823  close_leaving_mappings();
824  close_remapped();
825 
826  /* can't close it directly...
827  */
828  CONTROLMAP_MAP(s, c,
829  {
830  what_stat_debug(9, s);
831 
835  },
836  get_remapping_graph());
837 
838  close_remapping_graph();
839 }
840 
841 /* void propagate_synonym(s, old, new)
842  * statement s;
843  * entity old, new;
844  *
845  * what: propagates a new array/template synonym (old->new) from statement s.
846  * how: travels thru the control graph till the next remapping.
847  * input: the starting statement, plus the two entities.
848  * output: none.
849  * side effects:
850  * - uses the crtl_graph travelling.
851  * - set some static variables for the continuation decisions and switch.
852  * bugs or features:
853  * - not very efficient. Could have done something to deal with
854  * several synonyms at the same time...
855  * - what is done on an "incorrect" code is not clear.
856  */
857 
858 static entity
859  old_variable = entity_undefined, /* entity to be replaced, the primary? */
860  new_variable = entity_undefined; /* replacement */
861 static bool
862  array_propagation, /* true if an array is propagated, false if template */
863  array_used, /* true if the array was actually used */
864  array_modified; /* true if the array may be modified... */
865 static statement
866  initial_statement = statement_undefined; /* starting point */
867 
868 /* initialize both the remapping graph and the used dynamics for s
869  */
871 {
872  if (!bound_remapping_graph_p(s))
873  store_remapping_graph(s, make_control(s, NIL, NIL));
874 
875  if (!bound_used_dynamics_p(s))
876  store_used_dynamics(s, make_entities(NIL));
877 
878  if (!bound_modified_dynamics_p(s))
879  store_modified_dynamics(s, make_entities(NIL));
880 }
881 
883 {
884  control
885  c = load_remapping_graph(initial_statement),
886  n = (lazy_initialize_for_statement(s), load_remapping_graph(s));
887 
888  what_stat_debug(6, s);
889 
890  control_successors(c) =
891  gen_once(load_remapping_graph(s), control_successors(c));
893  gen_once(load_remapping_graph(initial_statement),
895 }
896 
898 {
899  entities es = load_used_dynamics(initial_statement);
901 }
902 
903 void
905 {
906  entities es = load_used_dynamics(s);
908 }
909 
911 {
912  entities es = load_modified_dynamics(initial_statement);
914 }
915 
916 static void add_alive_synonym(
917  statement s,
918  entity a)
919 {
920  entities es;
921 
922  /* lazy initialization
923  */
924  if (!bound_alive_synonym_p(s))
925  store_alive_synonym(s, make_entities(NIL));
926 
927  es = load_alive_synonym(s);
928  entities_list(es) = gen_once(a, entities_list(es));
929 }
930 
931 static void ref_rwt(reference r)
932 {
933  entity var = reference_variable(r);
934  if (var==old_variable || var==new_variable)
935  {
937  array_used = true;
938  }
939 }
940 
942 {
943  DEBUG_STAT(9, "considering", s);
944 
945  /* looks for direct references in s and switch them
946  */
949  statement_domain, gen_false, gen_null, /* STATEMENT */
950  unstructured_domain, gen_false, gen_null, /* UNSTRUCTURED ? */
951  reference_domain, gen_true, ref_rwt, /* REFERENCE */
952  NULL);
953 
954  /* whether the array may be written... by scanning the proper effects of s.
955  * (caution, was just switched to the new_variable!)
956  */
957  pips_debug(8, "statement %p, array %s, rw proper %d\n",
959 
961  {
963  {
964  if(store_effect_p(e)) {
967  {
968  pips_debug(9, "%s W in %p\n", entity_name(new_variable), s);
969  array_modified = true;
970  return;
971  }
972  }
973  }
974  }
975 }
976 
977 static bool
979 {
981 }
982 
983 /* true if not a remapping for old.
984  * if it is a remapping, operates the switch.
985  */
986 #define ret(why, what) \
987  { pips_debug(9, "ret %d because %s\n", what, why); return what; }
988 
989 static bool
991 {
993 
994  what_stat_debug(8, s);
995  DEBUG_STAT(9, "current", s);
996 
997  if (!instruction_call_p(i))
998  {
999  ret("not a call", true);
1000  }
1001  else
1002  {
1003  call c = instruction_call(i);
1004  entity fun = call_function(c);
1005 
1007  {
1008  entity
1010  array;
1011 
1012  DEBUG_STAT(8, "rename directive", s);
1013 
1015 
1016  if (safe_load_primary_entity(array)==primary)
1017  {
1020  ret("rename to the same", false);
1021  }
1022  }
1023  else if (realign_directive_p(fun) && array_propagation)
1024  {
1026  int nbofargs = gen_length(call_arguments(c));
1027 
1028  DEBUG_STAT(8, "realign directive", s);
1029 
1030  MAP(EXPRESSION, e,
1031  {
1032  nbofargs--;
1033  if (expression_reference_p(e))
1034  {
1036  entity var = reference_variable(r);
1037 
1038  if (nbofargs==0) /* up to the template! */
1039  ret("template of realign", true);
1040 
1041  if (safe_load_primary_entity(var)==primary)
1042  {
1043  /* the variable is realigned.
1044  */
1047  ret("realign array", false);
1048  }
1049  }
1050  /* else it may be a call because of ALIGN () WITH T()::X...
1051  */
1052  },
1053  call_arguments(c));
1054  }
1055  else if (redistribute_directive_p(fun))
1056  {
1059 
1060  DEBUG_STAT(8, "redistribute directive", s);
1061 
1062  MAP(EXPRESSION, e,
1063  {
1065 
1066  if (!entity_template_p(v)) /* up to the processor, stop */
1067  ret("processors of distribute", true);
1068 
1069  /* if template t is redistributed...
1070  */
1071  if (safe_load_primary_entity(v)==t)
1072  {
1073  if (array_propagation)
1076 
1077  ret("redistribute template", false);
1078  }
1079  },
1080  call_arguments(c));
1081  }
1082  else if (dead_fcd_directive_p(fun) && array_propagation)
1083  {
1085 
1086  MAP(EXPRESSION, e,
1087  if (primary==expression_to_entity(e)) ret("dead array", false),
1088  call_arguments(c));
1089  }
1090 
1091  ret("default", true);
1092  }
1093 }
1094 
1095 void
1097  statement s, /* starting statement for the propagation */
1098  entity old, /* entity to be replaced */
1099  entity new, /* replacement for the entity */
1100  bool is_array /* true if array, false if template */)
1101 {
1103 
1104  what_stat_debug(3, s);
1105  pips_debug(3, "%s -> %s (%s)\n", entity_name(old), entity_name(new),
1106  is_array? "array": "template");
1107  DEBUG_STAT(7, "before propagation", get_current_module_statement());
1108 
1110  array_propagation = is_array;
1111  array_used = false;
1112  array_modified = false;
1113  initial_statement = s;
1114 
1116 
1118 
1121 
1123 
1126 
1129 
1130  DEBUG_STAT(7, "after propagation", get_current_module_statement());
1131 
1132  pips_debug(4, "out\n");
1133 }
1134 
1135 /********************************* REMAPPING GRAPH REMAPS "SIMPLIFICATION" */
1136 
1137 /* for statement s
1138  * - remapped arrays
1139  * - reaching mappings (1 per array, or more)
1140  * - leaving mappings (1 per remapped array, to simplify)
1141  */
1143 statement s;
1144 {
1145  list /* of entities */ le = NIL, lp = NIL, ll = NIL;
1146  entity old, new;
1147 
1148  what_stat_debug(4, s);
1149 
1150  MAP(RENAMING, r,
1151  {
1152  old = renaming_old(r);
1153  new = renaming_new(r);
1154 
1155  le = gen_once(old, le);
1156  lp = gen_once(load_primary_entity(old), lp);
1157  ll = gen_once(new, ll);
1158  },
1159  load_renamings(s));
1160 
1161  store_reaching_mappings(s, make_entities(le));
1162  store_remapped(s, make_entities(lp));
1163  store_leaving_mappings(s, make_entities(ll));
1164 }
1165 
1167 {
1168  entities leaving = load_leaving_mappings(s);
1169  list /* of entities */
1170  ll = entities_list(leaving),
1171  ln = gen_copy_seq(ll),
1172  lr = entities_list(load_remapped(s)),
1173  lu = entities_list(load_used_dynamics(s));
1174  entity primary;
1175 
1176  MAP(ENTITY, array,
1177  {
1178  primary = load_primary_entity(array);
1179 
1180  if (gen_in_list_p(primary, lr) && /* REMAPPED and */
1181  !gen_in_list_p(primary, lu)) /* NOT USED */
1182  {
1183  what_stat_debug(4, s);
1184  pips_debug(4, "removing %s\n", entity_name(array));
1185  gen_remove(&ln, array); /* => NOT LEAVED */
1186  }
1187  },
1188  ll);
1189 
1190  gen_free_list(ll), entities_list(leaving) = ln;
1191 }
1192 
1193 /* must be called after useless leaving mappings removal */
1195 {
1196  store_maybeuseful_mappings(s, copy_entities(load_leaving_mappings(s)));
1197 }
1198 
1200 {
1201  entities er = load_reaching_mappings(s);
1202  list /* of entity */ newr = NIL, /* new reachings */
1203  lrem = entities_list(load_remapped(s));
1204 
1206 
1207  MAP(CONTROL, c,
1208  {
1209  MAP(ENTITY, e,
1210  {
1211  if (gen_in_list_p(load_primary_entity(e), lrem))
1212  newr = gen_once(e, newr);
1213  },
1214  entities_list(load_leaving_mappings(control_statement(c))));
1215  },
1216  control_predecessors(load_remapping_graph(s)));
1217 
1218  entities_list(er) = newr;
1219 }
1220 
1221 /* more options, such as may or must? */
1222 static list /* of statement */
1224  statement s,
1225  list /* of statement */ ls,
1226  entities (*built)(statement),
1227  entities (*condition)(statement),
1228  bool local, /* local or remote condition */
1229  bool forward) /* backward or forward */
1230 {
1231  bool modified = false;
1232  entities built_set = built(s);
1233  list /* of entity */
1234  lrem = entities_list(load_remapped(s)),
1235  lbuilt = entities_list(built_set);
1236  control current = load_remapping_graph(s);
1237 
1238  MAP(CONTROL, c,
1239  {
1240  statement sc = control_statement(c);
1241  list /* of entity */ lp_rem = entities_list(load_remapped(sc));
1242  list /* idem */ lp_cond = entities_list(condition(local?s:sc));
1243 
1244  MAP(ENTITY, e,
1245  {
1246  entity prim = load_primary_entity(e);
1247 
1248  if (gen_in_list_p(prim, lrem) &&
1249  gen_in_list_p(prim, lp_rem) &&
1250  !gen_in_list_p(prim, lp_cond) &&
1251  !gen_in_list_p(e, lbuilt))
1252  {
1253  what_stat_debug(5, s);
1254  pips_debug(5, "adding %s from\n", entity_local_name(e));
1255  what_stat_debug(5, sc);
1256 
1257  lbuilt = CONS(ENTITY, e, lbuilt);
1258  modified = true;
1259  }
1260  },
1261  entities_list(built(sc)));
1262  },
1264 
1265  /* if the built set was modified, must propagate at next step... */
1266  if (modified)
1267  {
1268  entities_list(built_set) = lbuilt;
1269  MAP(CONTROL, c, ls = gen_once(control_statement(c), ls),
1271  }
1272 
1273  return ls;
1274 }
1275 
1276 static list /* of statements */
1278  statement s,
1279  list /* of statements */ ls)
1280 {
1282  (s, ls, load_reaching_mappings, load_used_dynamics, false, true);
1283 }
1284 
1285 static list /* of statements */
1287  statement s,
1288  list /* of statement */ ls)
1289 {
1291  (s, ls, load_maybeuseful_mappings, load_modified_dynamics, true, false);
1292 }
1293 
1295  entity primary,
1296  entities es)
1297 {
1298  list /* of entity(s) */ le = gen_copy_seq(entities_list(es));
1299 
1300  MAP(ENTITY, array,
1301  {
1302  if (load_primary_entity(array)==primary)
1304  },
1305  le);
1306 
1307  gen_free_list(le);
1308 }
1309 
1311 {
1312  entities remapped = load_remapped(s),
1313  reaching = load_reaching_mappings(s),
1314  leaving = load_leaving_mappings(s);
1315  list /* of entity(s) */ le = gen_copy_seq(entities_list(remapped)),
1316  lu = entities_list(load_used_dynamics(s));
1317 
1318  MAP(ENTITY, primary,
1319  {
1320  pips_debug(5, "considering array %s\n", entity_name(primary));
1321 
1322  if (!storage_formal_p(entity_storage(primary)) &&
1323  !gen_in_list_p(primary, lu))
1324  {
1325  remove_from_entities(primary, remapped);
1326  remove_from_entities(primary, reaching);
1327  remove_from_entities(primary, leaving);
1328  }
1329  },
1330  le);
1331 
1332  gen_free_list(le);
1333 }
1334 
1335 /* regenerate the renaming structures after the optimizations performed on
1336  * the remapping graph.
1337  */
1339 {
1340  list /* of entity(s) */
1341  lr = entities_list(load_reaching_mappings(s)),
1342  ll = entities_list(load_leaving_mappings(s)),
1343  ln = NIL;
1344 
1345  what_stat_debug(4, s);
1346 
1347  MAP(ENTITY, target,
1348  {
1349  entity primary = load_primary_entity(target);
1350  bool some_source_found = false;
1351 
1352  MAP(ENTITY, source,
1353  {
1354  if (load_primary_entity(source)==primary && source!=target)
1355  {
1356  pips_debug(4, "%s -> %s\n",
1357  entity_name(source), entity_name(target));
1358  ln = CONS(RENAMING, make_renaming(source, target), ln);
1359  some_source_found = true;
1360  }
1361  },
1362  lr);
1363 
1364  /* ensures some remapping to enforce an update of the status,
1365  * which may be necessary, for instance if KILL was used.
1366  */
1367  if (!some_source_found)
1368  {
1369  pips_debug(7, "no source found for %s\n", entity_name(target));
1370  ln = CONS(RENAMING, make_renaming(target, target), ln);
1371  }
1372  },
1373  ll);
1374 
1375  {
1376  list /* of renaming(s) */ l = load_renamings(s);
1377  gen_map((gen_iter_func_t)gen_free, l), gen_free_list(l); /* ??? */
1378  update_renamings(s, ln);
1379  }
1380 }
1381 
1382 static list /* of statements */
1384 {
1385  list /* of statements */ l = NIL;
1386  CONTROLMAP_MAP(s, c,
1387  {
1388  pips_debug(9, "%p -> %p\n", s, c);
1389  l = CONS(STATEMENT, s, l);
1390  },
1391  get_remapping_graph());
1392  return l;
1393 }
1394 
1395 /* functions used for debug.
1396  */
1398 {
1400  int so = statement_ordering(s);
1401  fprintf(stderr, "(%d:%d:%" PRIdPTR "), ",
1403  statement_ordering(s));
1404 }
1405 
1406 #define elst_ifdef(what, name, s) \
1407  if (bound_##name##_p(s)){DEBUG_ELST(1, what, entities_list(load_##name(s)));}\
1408  else pips_debug(1, "no " what "\n");
1409 
1411 {
1412  control c = load_remapping_graph(s);
1413 
1414  what_stat_debug(1, s);
1415 
1416  fprintf(stderr, "predecessors: ");
1418  fprintf(stderr, "\nsuccessors: ");
1420  fprintf(stderr, "\n");
1421 
1422  elst_ifdef("remapped", remapped, s);
1423  elst_ifdef("used", used_dynamics, s);
1424  elst_ifdef("modified", modified_dynamics, s);
1425  elst_ifdef("reaching", reaching_mappings, s);
1426  elst_ifdef("leaving", leaving_mappings, s);
1427  elst_ifdef("maybe useful", maybeuseful_mappings, s);
1428 }
1429 
1430 static void
1432  string when,
1433  list /* of statement */ ls)
1434 {
1435  fprintf(stderr, "[dump_remapping_graph] for %s\n", when);
1437  fprintf(stderr, "[dump_remapping_graph] done\n");
1438 }
1439 
1441 {
1443 }
1444 
1445 /* void simplify_remapping_graph()
1446  *
1447  * what: simplifies the remapping graph.
1448  * how: propagate unused reaching mappings to the next remappings,
1449  * and remove unnecessary remappings.
1450  * input: none.
1451  * output: none.
1452  * side effects: all is there!
1453  * - the remapping graph remappings are modified.
1454  * - some static structures are used.
1455  * - current module statement needed.
1456  * bugs or features:
1457  * - special treatment of the current module statement to model the
1458  * initial mapping at the entry of the module. The initial mapping may
1459  * be modified by the algorithm if it is remapped before being used.
1460  * - ??? the convergence and correctness are to be proved.
1461  * - expected complexity: n vertices (small!), q nexts, m arrays, r remaps.
1462  * assumes fast sets instead of lists, with O(1) tests/add/del...
1463  * closure: O(n^2*vertex_operation) (if it is a simple propagation...)
1464  * map: O(n*vertex_operation)
1465  * C = n^2 q m r
1466  */
1468 {
1469  list /* of statements */ ls = list_of_remapping_statements();
1471  what_stat_debug(4, root);
1472 
1473  ifdebug(8) dump_remapping_graph("0", ls);
1474 
1479 
1480  ifdebug(4) dump_remapping_graph("1", ls);
1481 
1482  pips_debug(4, "used array propagation\n");
1484 
1485  pips_debug(4, "may be useful mapping propagation\n");
1487 
1488  ifdebug(4) dump_remapping_graph("2", ls);
1489 
1490  if (bound_remapped_p(root)) remove_unused_remappings(root);
1491 
1493 
1494  gen_free_list(ls);
1495 }
1496 
1497 /* what: returns the list of alive arrays for statement s and template t.
1498  * how: uses the alive_synonym, and computes the defaults.
1499  * input: statement s and template t which are of interest.
1500  * output: a list of entities which is allocated.
1501  * side effects: none.
1502  */
1503 list /* of entities */
1505  statement s,
1506  entity t)
1507 {
1508  list /* of entities */ l = NIL, lseens = NIL; /* to tag seen primaries. */
1509 
1510  pips_assert("template", entity_template_p(t) && primary_entity_p(t));
1511  pips_debug(7, "for template %s\n", entity_name(t));
1512 
1513  /* ??? well, it is not necessarily initialized, I guess...
1514  */
1515  if (!bound_alive_synonym_p(s))
1516  store_alive_synonym(s, make_entities(NIL));
1517 
1518  /* first the alive list is scanned.
1519  */
1520  MAP(ENTITY, array,
1521  {
1523 
1524  if (safe_load_primary_entity(ta)==t)
1525  l = CONS(ENTITY, array, l);
1526 
1527  pips_debug(8, "adding %s as alive\n", entity_name(array));
1528 
1529  lseens = CONS(ENTITY, load_primary_entity(array), lseens);
1530  },
1531  entities_list(load_alive_synonym(s)));
1532 
1533  /* second the defaults are looked for. namely the primary entities.
1534  */
1535  MAP(ENTITY, array,
1536  {
1537  if (primary_entity_p(array) && !gen_in_list_p(array, lseens))
1538  {
1540  l = CONS(ENTITY, array, l);
1541 
1542  pips_debug(8, "adding %s as default\n", entity_name(array));
1543 
1544  lseens = CONS(ENTITY, array, lseens);
1545  }
1546  },
1548 
1549  DEBUG_ELST(9, "seen arrays", lseens);
1550  gen_free_list(lseens);
1551 
1552  DEBUG_ELST(7, "returned alive arrays", l);
1553  return l;
1554 }
1555 
1556 /* statement generate_copy_loop_nest(src, trg)
1557  * entity src, trg;
1558  *
1559  * what: generates a parallel loop nest that copies src in trg.
1560  * how: by building the corresponding AST.
1561  * input: the two entities, which should be arrays with the same shape.
1562  * output: a statement containing the loop nest.
1563  * side effects:
1564  * - adds a few new variables for the loop indexes.
1565  * bugs or features:
1566  * - could be more general?
1567  */
1569  entity src,
1570  entity trg)
1571 {
1572  type t = entity_type(src);
1573  list /* of entities */ indexes = NIL,
1574  /* of expressions */ idx_expr,
1575  /* of dimensions */ dims;
1577  entity module;
1578  int ndims, i;
1579 
1580  if (src==trg) return make_empty_statement();
1581 
1582  pips_assert("valid arguments",
1584  type_variable_p(t) &&
1585  load_primary_entity(src)==load_primary_entity(trg)); /* ??? */
1586 
1588  ndims = gen_length(dims);
1589 
1590  /* builds the set of indexes needed to scan the dimensions.
1591  */
1592  for(module=get_current_module_entity(), i=ndims; i>0; i--)
1593  indexes = CONS(ENTITY,
1595  indexes);
1596 
1597  idx_expr = entities_to_expressions(indexes);
1598 
1599  /* builds the assign statement to put in the body.
1600  * TRG(indexes) = SRC(indexes)
1601  */
1603  (reference_to_expression(make_reference(trg, idx_expr)),
1605 
1606  /* builds the copy loop nest
1607  */
1608  for(; ndims>0; POP(dims), POP(indexes), ndims--)
1609  {
1610  dimension d = DIMENSION(CAR(dims));
1611 
1613  (make_loop(ENTITY(CAR(indexes)),
1616  int_to_expression(1)),
1617  current,
1620  NIL));
1621  }
1622 
1623  DEBUG_STAT(7, concatenate(entity_name(src), " -> ", entity_name(trg), NULL),
1624  current);
1625 
1626  return current;
1627 }
1628 
1629 /* that is all
1630  */
void free_align(align p)
Definition: hpf.c:19
void free_distribute(distribute p)
Definition: hpf.c:103
align copy_align(align p)
ALIGN.
Definition: hpf.c:16
dynamic_status make_dynamic_status(entity_entities a1, entitymap a2, statement_renamings a3, statement_entities a4)
Definition: hpf_private.c:208
entities copy_entities(entities p)
ENTITIES.
Definition: hpf_private.c:214
entities make_entities(list a)
Definition: hpf_private.c:250
renaming make_renaming(entity a1, entity a2)
Definition: hpf_private.c:881
execution make_execution(enum execution_utype tag, void *val)
Definition: ri.c:838
call make_call(entity a1, list a2)
Definition: ri.c:269
loop make_loop(entity a1, range a2, statement a3, entity a4, execution a5, list a6)
Definition: ri.c:1301
storage make_storage(enum storage_utype tag, void *val)
Definition: ri.c:2273
ram make_ram(entity a1, entity a2, intptr_t a3, list a4)
Definition: ri.c:1999
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
void free_storage(storage p)
Definition: ri.c:2231
control make_control(statement a1, list a2, list a3)
Definition: ri.c:523
range make_range(expression a1, expression a2, expression a3)
Definition: ri.c:2041
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
bool next_ctrl_graph_travel(statement *)
Definition: graph.c:325
void init_ctrl_graph_travel(statement, bool(*)(statement))
Definition: graph.c:315
void close_ctrl_graph_travel(void)
Definition: graph.c:340
void print_align(align a)
this is a set of functions to help hpfc debugging
Definition: debug-util.c:38
bool array_distribution_similar_p(entity a1, entity a2)
Definition: dynamic.c:578
void close_dynamic_locals()
Definition: dynamic.c:817
static void ref_rwt(reference r)
Definition: dynamic.c:931
static void remove_from_entities(entity primary, entities es)
Definition: dynamic.c:1294
static void lazy_initialize_for_statement(statement s)
starting point
Definition: dynamic.c:870
static void initialize_maybeuseful_mappings(statement s)
must be called after useless leaving mappings removal
Definition: dynamic.c:1194
void close_dynamic_status()
Definition: dynamic.c:117
static bool same_alignment_in_list_p(alignment a, list l)
comparison of ALIGN.
Definition: dynamic.c:385
static void dump_remapping_graph(string when, list ls)
Definition: dynamic.c:1431
static void add_dynamic_synonym(entity new_e, entity e)
what: new_e is stored as a synonym of e.
Definition: dynamic.c:149
list alive_arrays(statement s, entity t)
what: returns the list of alive arrays for statement s and template t.
Definition: dynamic.c:1504
static list propagate_used_arrays(statement s, list ls)
of statements
Definition: dynamic.c:1277
static entity new_synonym(entity e)
builds a synonym for entity e.
Definition: dynamic.c:198
static entity new_variable
entity to be replaced, the primary?
Definition: dynamic.c:860
void init_dynamic_locals()
DYNAMIC LOCAL DATA.
Definition: dynamic.c:806
static entity new_synonym_template(entity t, distribute di)
builds a new synonym for template t, the distribution of which will be di.
Definition: dynamic.c:319
static bool same_distribute_p(distribute d1, distribute d2)
comparison of DISTRIBUTE.
Definition: dynamic.c:353
static void dump_remapping_graph_info(statement s)
Definition: dynamic.c:1410
void set_dynamic_status(dynamic_status d)
Definition: dynamic.c:108
void set_similar_mappings_for_updates(void)
Definition: dynamic.c:162
static list add_once_to_renaming_list(list l, entity o, entity n)
of renaming
Definition: dynamic.c:665
static list list_of_remapping_statements()
of statements
Definition: dynamic.c:1383
bool same_primary_entity_p(entity e1, entity e2)
Definition: dynamic.c:70
static bool continue_propagation_p(statement s)
Definition: dynamic.c:990
void init_dynamic_status()
DYNAMIC STATUS management.
Definition: dynamic.c:81
void reset_dynamic_status()
Definition: dynamic.c:90
void hpfc_translate_call_with_distributed_args(statement s, call c)
??? only simple calls are handled.
Definition: dynamic.c:687
dynamic_status get_dynamic_status()
Definition: dynamic.c:99
static void add_alive_synonym(statement s, entity a)
Definition: dynamic.c:916
static void simple_switch_old_to_new(statement s)
Definition: dynamic.c:941
static bool same_distribution_p(distribution d1, distribution d2)
array_distribution_similar_p
Definition: dynamic.c:523
bool conformant_templates_p(entity t1, entity t2)
Definition: dynamic.c:405
#define RETAL(msg, res)
Definition: dynamic.c:531
#define RET(msg, what)
Definition: dynamic.c:574
#define ret(why, what)
true if not a remapping for old.
Definition: dynamic.c:986
static void add_as_a_modified_variable(entity e)
Definition: dynamic.c:910
static void print_control_ordering(control c)
functions used for debug.
Definition: dynamic.c:1397
bool(* dynamic_entity_p)(entity)
as expected, true if entity e is dynamic.
Definition: dynamic.c:145
void dump_current_remapping_graph(string when)
Definition: dynamic.c:1440
void simplify_remapping_graph(void)
void simplify_remapping_graph()
Definition: dynamic.c:1467
void propagate_synonym(statement s, entity old, entity new, bool is_array)
Definition: dynamic.c:1096
static list propagate_maybeuseful_mappings(statement s, list ls)
of statements
Definition: dynamic.c:1286
bool hpfc_call_with_distributed_args_p(call c)
whether call c inplies a distributed argument
Definition: dynamic.c:645
static void regenerate_renamings(statement s)
regenerate the renaming structures after the optimizations performed on the remapping graph.
Definition: dynamic.c:1338
static void initialize_reaching_propagation(statement s)
for statement s
Definition: dynamic.c:1142
void set_entity_as_dynamic(entity e)
a new dynamic entity is stored.
Definition: dynamic.c:130
static void add_as_a_used_variable(entity e)
Definition: dynamic.c:897
static list propagation_on_remapping_graph(statement s, list ls, entities(*built)(statement), entities(*condition)(statement), bool local, bool forward)
more options, such as may or must?
Definition: dynamic.c:1223
static entity new_synonym_array(entity a, align al)
builds a new synonym for array a, the alignment of which will be al.
Definition: dynamic.c:306
void hpfc_check_for_similarities(list le)
check all dynamic arrays for some similars...
Definition: dynamic.c:269
static entity old_variable
void propagate_synonym(s, old, new) statement s; entity old, new;
Definition: dynamic.c:859
static bool same_align_p(align a1, align a2)
Definition: dynamic.c:418
entity safe_load_primary_entity(entity e)
HPFC module by Fabien COELHO.
Definition: dynamic.c:61
static bool rename_directive_p(entity f)
Definition: dynamic.c:978
static bool same_alignment_p(entity e1, entity t1, alignment a1, entity e2, entity t2, alignment a2)
Definition: dynamic.c:535
void add_as_a_used_dynamic_to_statement(statement s, entity e)
Definition: dynamic.c:904
align new_align_with_template(align a, entity t)
Definition: dynamic.c:474
static void remove_not_remapped_leavings(statement s)
Definition: dynamic.c:1166
entity template_synonym_distributed_as(entity temp, distribute d)
what: finds or creates a new entity distributed as needed.
Definition: dynamic.c:491
static bool array_used
true if an array is propagated, false if template
Definition: dynamic.c:863
static void remove_unused_remappings(statement s)
Definition: dynamic.c:1310
static bool array_modified
true if the array was actually used
Definition: dynamic.c:864
statement generate_copy_loop_nest(entity src, entity trg)
statement generate_copy_loop_nest(src, trg) entity src, trg;
Definition: dynamic.c:1568
static statement initial_statement
true if the array may be modified...
Definition: dynamic.c:866
static bool conformant_entities_p(entity e1, entity e2)
Definition: dynamic.c:329
static bool array_propagation
replacement
Definition: dynamic.c:862
static void add_as_a_closing_statement(statement s)
Definition: dynamic.c:882
static void check_for_similarity(entity a, list others)
Definition: dynamic.c:230
entity array_synonym_aligned_as(entity array, align a)
entity array_synonym_aligned_as(array, a) entity array; align a;
Definition: dynamic.c:449
static void reinitialize_reaching_mappings(statement s)
Definition: dynamic.c:1199
#define elst_ifdef(what, name, s)
Definition: dynamic.c:1406
list load_proper_rw_effects_list(statement)
bool bound_proper_rw_effects_p(statement)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define effect_write_p(eff)
bool store_effect_p(effect)
Definition: effects.c:1062
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
void gen_free(gen_chunk *obj)
version without shared_pointers.
Definition: genClib.c:992
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
Definition: statement.c:597
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
void gen_multi_recurse(void *o,...)
Multi recursion visitor function.
Definition: genClib.c:3428
bool gen_false(__attribute__((unused)) gen_chunk *unused)
Return false and ignore the argument.
Definition: genClib.c:2796
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
instruction make_instruction_block(list statements)
Build an instruction block from a list of statements.
Definition: instruction.c:106
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
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 POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
void gen_map(gen_iter_func_t fp, const list l)
Definition: list.c:172
list gen_once(const void *vo, list l)
Prepend an item to a list only if it is not already in the list.
Definition: list.c:722
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
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
#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
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
void gen_closure(list(*iterate)(), list(*initial)())
void gen_closure(iterate, initial) list [of X] (*iterate)([ X, list of X ]), initial;
Definition: list.c:839
statement make_assign_statement(expression, expression)
Definition: statement.c:583
void fix_sequence_statement_attributes(statement)
Since blocks are not represented in Fortran, they cannot carry a label.
Definition: statement.c:2016
void store_new_node_variable(entity new, entity old)
#define alignment_templatedim(x)
Definition: hpf.h:136
#define DISTRIBUTION(x)
DISTRIBUTION.
Definition: hpf.h:180
#define distribution_style(x)
Definition: hpf.h:210
#define alignment_constant(x)
Definition: hpf.h:140
#define align_template(x)
Definition: hpf.h:98
#define align_alignment(x)
Definition: hpf.h:96
#define distribute_distribution(x)
Definition: hpf.h:174
#define ALIGNMENT(x)
ALIGNMENT.
Definition: hpf.h:102
#define alignment_rate(x)
Definition: hpf.h:138
#define alignment_undefined_p(x)
Definition: hpf.h:109
#define style_tag(x)
Definition: hpf.h:258
#define alignment_arraydim(x)
Definition: hpf.h:134
#define distribute_processors(x)
Definition: hpf.h:176
#define distribution_parameter(x)
Definition: hpf.h:212
@ is_style_none
Definition: hpf.h:237
#define dynamic_status_dynamics(x)
Definition: hpf_private.h:376
#define renaming_old(x)
Definition: hpf_private.h:969
#define entities_list(x)
Definition: hpf_private.h:414
#define renaming_new(x)
Definition: hpf_private.h:971
#define dynamic_status_renamings(x)
Definition: hpf_private.h:380
#define RENAMING(x)
RENAMING.
Definition: hpf_private.h:939
#define dynamic_status_tokeep(x)
Definition: hpf_private.h:382
#define dynamic_status_primary(x)
Definition: hpf_private.h:378
void get_entity_dimensions(entity e, int dim, int *plow, int *pup)
Definition: hpfc-util.c:651
int HpfcExpressionToInt(expression e)
HpfcExpressionToInt(e)
Definition: hpfc-util.c:569
distribution FindDistributionOfProcessorDim(list ldi, int dim, int *tdim)
Definition: hpfc-util.c:421
alignment FindAlignmentOfTemplateDim(list lal, int dim)
Definition: hpfc-util.c:389
#define src(name, suf)
HPFC by Fabien Coelho, May 1993 and later...
Definition: compile.c:41
entity hpfc_new_variable(entity module, basic b)
Definition: compile.c:632
#define what_stat_debug(level, stat)
#define DEBUG_ELST(D, W, L)
#define RENAME_SUFFIX
#define DEBUG_STAT(D, W, S)
#define primary_entity_p(a)
void add_a_dynamic(entity c)
local primary dynamics
Definition: directives.c:99
entities load_dynamic_hpf(entity)
entity hpfc_name_to_entity(const char *)
Definition: run-time.c:817
void store_hpf_distribution(entity, distribute)
entity load_similar_mapping(entity)
entity load_new_node(entity)
void close_dynamic_hpf(void)
list load_renamings(statement)
bool entity_template_p(entity)
void set_template(entity)
void store_similar_mapping(entity, entity)
void store_hpf_alignment(entity, align)
void update_renamings(statement, list)
void set_dynamic_hpf(entity_entities)
distribute load_hpf_distribution(entity)
void init_maybeuseful_mappings(void)
void init_similar_mapping(void)
void reset_maybeuseful_mappings(void)
void close_similar_mapping(void)
void init_renamings(void)
entity load_primary_entity(entity)
statement_entities get_maybeuseful_mappings(void)
void reset_dynamic_hpf(void)
statement_renamings get_renamings(void)
void set_maybeuseful_mappings(statement_entities)
bool bound_new_node_p(entity)
void close_primary_entity(void)
bool bound_similar_mapping_p(entity)
align load_hpf_alignment(entity)
void init_primary_entity(void)
entity_entities get_dynamic_hpf(void)
void close_maybeuseful_mappings(void)
bool bound_dynamic_hpf_p(entity)
void set_primary_entity(entitymap)
void store_primary_entity(entity, entity)
entitymap get_primary_entity(void)
void reset_renamings(void)
list list_of_distributed_arrays(void)
void set_renamings(statement_renamings)
void set_array_as_distributed(entity)
void store_dynamic_hpf(entity, entities)
void reset_primary_entity(void)
void close_renamings(void)
bool bound_primary_entity_p(entity)
void store_maybeuseful_mappings(statement, entities)
bool array_distributed_p(entity)
void init_dynamic_hpf(void)
entities load_maybeuseful_mappings(statement)
#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 pips_user_error
Definition: misc-local.h:147
#define DYNAMIC_AREA_LOCAL_NAME
Definition: naming-local.h:69
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define GENERIC_GLOBAL_FUNCTION(name, type)
#define same_string_p(s1, s2)
list(* gen_closure_func_t)(gen_chunk *, list)
Definition: newgen_list.h:335
int bool
we cannot use an enum or stdbool because we need to be compatible with newgen, thus boolean need to h...
Definition: newgen_types.h:78
int tag
TAG.
Definition: newgen_types.h:92
void(* gen_iter_func_t)(void *)
Definition: newgen_types.h:116
#define UU
Definition: newgen_types.h:98
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
static char * module
Definition: pips.c:74
#define HPF_PREFIX
moved here because needed by syntax:-(
#define loop_to_statement(l)
#define ORDERING_NUMBER(o)
#define ORDERING_STATEMENT(o)
#define call_to_statement(c)
#define make_empty_statement
An alias for make_empty_block_statement.
entity FindEntity(const char *package, const char *name)
Retrieve an entity from its package/module name and its local name.
Definition: entity.c:1503
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
list entities_to_expressions(list l_ent)
build a list of expressions from a list of entities
Definition: entity.c:2703
entity entity_empty_label(void)
Definition: entity.c:1105
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
entity FindOrCreateEntityLikeModel(const char *package, const char *name, entity model)
hmmm...
Definition: entity.c:3136
expression reference_to_expression(reference r)
Definition: expression.c:196
reference expression_to_reference(expression e)
Definition: expression.c:212
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
bool expression_equal_p(expression e1, expression e2)
Syntactic equality e1==e2.
Definition: expression.c:1347
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
entity expression_to_entity(expression e)
just returns the entity of an expression, or entity_undefined
Definition: expression.c:3140
bool realign_directive_p(entity f)
Definition: hpfc.c:62
bool dead_fcd_directive_p(entity f)
Definition: hpfc.c:74
bool redistribute_directive_p(entity f)
Definition: hpfc.c:68
bool hpf_directive_entity_p(entity e)
Definition: hpfc.c:56
basic MakeBasic(int)
END_EOLE.
Definition: type.c:128
dimension FindIthDimension(entity, int)
Definition: type.c:1180
void AddEntityToDeclarations(entity, entity)
END_EOLE.
Definition: variable.c:108
int SizeOfIthDimension(entity, int)
this function returns the size of the ith dimension of a variable e.
Definition: size.c:453
int NumberOfDimension(entity)
Definition: size.c:588
entity find_ith_parameter(entity, int)
Definition: util.c:93
@ is_basic_int
Definition: ri.h:571
#define unstructured_domain
newgen_type_domain_defined
Definition: ri.h:442
#define storage_formal_p(x)
Definition: ri.h:2522
#define call_function(x)
Definition: ri.h:709
#define reference_variable(x)
Definition: ri.h:2326
#define control_predecessors(x)
Definition: ri.h:943
#define value_intrinsic_p(x)
Definition: ri.h:3074
#define CONTROLMAP_MAP(k, v, c, f)
Definition: ri.h:900
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define statement_ordering(x)
Definition: ri.h:2454
#define dimension_lower(x)
Definition: ri.h:980
#define type_variable(x)
Definition: ri.h:2949
#define entity_storage(x)
Definition: ri.h:2794
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define CONTROL(x)
CONTROL.
Definition: ri.h:910
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
@ is_storage_ram
Definition: ri.h:2492
#define reference_domain
newgen_range_domain_defined
Definition: ri.h:338
#define entity_undefined
Definition: ri.h:2761
#define entity_name(x)
Definition: ri.h:2790
#define dimension_upper(x)
Definition: ri.h:982
#define control_successors(x)
Definition: ri.h:945
#define instruction_call_p(x)
Definition: ri.h:1527
#define variable_dimensions(x)
Definition: ri.h:3122
#define statement_instruction(x)
Definition: ri.h:2458
#define instruction_call(x)
Definition: ri.h:1529
@ is_execution_parallel
Definition: ri.h:1190
#define call_arguments(x)
Definition: ri.h:711
#define control_statement(x)
Definition: ri.h:941
#define entity_type(x)
Definition: ri.h:2792
#define type_variable_p(x)
Definition: ri.h:2947
#define statement_undefined
Definition: ri.h:2419
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
#define entity_initial(x)
Definition: ri.h:2796
Value b2
Definition: sc_gram.c:105
Value b1
booleen indiquant quel membre est en cours d'analyse
Definition: sc_gram.c:105
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
s1
Definition: set.c:247
#define ifdebug(n)
Definition: sg.c:47
static entity array
#define intptr_t
Definition: stdint.in.h:294
GENERIC_LOCAL_FUNCTION(directives, step_directives)
Copyright 2007, 2008, 2009 Alain Muller, Frederique Silber-Chaussumier.
static size_t current
Definition: string.c:115
The structure used to build lists in NewGen.
Definition: newgen_list.h:41