PIPS
o-analysis.c
Go to the documentation of this file.
1 /*
2 
3  $Id: o-analysis.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 /* Overlap Analysis Module for HPFC
28  *
29  * Fabien Coelho, August 1993
30  */
31 
32 #include "defines-local.h"
33 #include "prettyprint.h"
34 #include "access_description.h"
35 
36 #include "effects-generic.h"
37 
38 static list lblocks = NIL, lloop = NIL;
39 
40 GENERIC_LOCAL_FUNCTION(entity_variable_used, entity_int)
41 
42 /* true if there is no cyclic distribution for the array
43  */
45 {
46  int dim = NumberOfDimension(array);
47  tag n;
48 
49  for(; dim>0; dim--)
50  {
51  n = new_declaration_tag(array, dim);
53  /* distributed && (nd==is_hpf_newdecl_none)) ?
54  * ??? the case is not handled later on
55  */
56  return(false);
57  }
58 
59  return(true);
60 }
61 
62 /* true if indices are constants or index
63  */
65 {
67  int dim = 1;
68 
69  ifdebug(6) {
70  pips_debug(6, "considering reference: ");
71  print_reference(r);
72  fprintf(stderr,"\n");
73  }
74 
75  MAP(EXPRESSION, e,
76  {
78  int p;
79  bool b1 = ith_dim_distributed_p(array, dim, &p);
80  bool b2 = ((!b1) ? local_integer_constant_expression(e) : false);
81 
82  pips_debug(7, "%s(DIM=%d), distributed %d, locally constant %d\n",
83  entity_name(array), dim, b1, b2);
84 
85  if (!b2)
86  {
87  if (normalized_complex_p(n))
88  /* cannot decide, so it is supposed to be false */
89  {
90  pips_debug(7, "returning false (complex)\n");
91  return false;
92  }
93  else
94  {
96  int s = vect_size(v);
97 
98  if (s>1)
99  {
100  ifdebug(7) {
101  pips_debug(7, "returning false, vect size %d>1\n", s);
102  vect_debug(v);
103  }
104  return false;
105  }
106 
107  if ((s==1) &&
108  (!entity_loop_index_p((entity)v->var)) &&
110  {
111  pips_debug(7, "returning false (not simple)\n");
112  return false;
113  }
114  else
115  if (entity_loop_index_p((entity)v->var))
116  {
117  /* ??? checks that there is a shift alignment,
118  * what shouldn't be necessary...
119  */
121  int rate = al==alignment_undefined?
123 
124  if (rate!=0 && rate!=1)
125  {
126  pips_debug(7, "returning false (stride)\n");
127  return(false);
128  }
129  }
130  }
131  }
132 
133  dim++;
134  },
135  reference_indices(r));
136 
137  pips_debug(7, "returning TRUE!\n");
138  return true;
139 }
140 
141 /* true if references are aligned or, for constants, on the same processor...
142  */
143 static bool
145  reference r1,
146  reference r2,
147  list lvref,
148  list lkref)
149 {
150  entity e2 = reference_variable(r2), template = array_to_template(e2);
151  list lv = lvref, lk = lkref;
152  bool result = true;
153  int i = 1 ;
154 
155  pips_debug(7, "arrays %s and %s\n",
157 
158  for ( ; (lk!=NIL) ; POP(lv), POP(lk))
159  {
160  tag t = access_tag(INT(CAR(lk)));
161  Pvecteur v = (Pvecteur) PVECTOR(CAR(lv));
162  Value vt = vect_coeff(TEMPLATEV, v),
163  vd = vect_coeff(DELTAV, v),
164  vs = vect_coeff(TSHIFTV, v);
165  int p,
167  tpl = VALUE_TO_INT(vt),
168  dlt = VALUE_TO_INT(vd),
169  tsh = VALUE_TO_INT(vs);
170 
171  if ((t==not_aligned) ||
172  ((t==aligned_constant) &&
173  (processor_number(template, tpldim, tpl, &p)!=
174  processor_number(template, tpldim, tpl-dlt, &p))) ||
175  ((t==aligned_shift) && (tsh!=0)))
176  return false;
177 
178  i++;
179  }
180 
181  return result;
182 }
183 
184 /* true if the given template elements on the specified dimension
185  * are mapped on the same processor.
186  */
187 static bool on_same_proc_p(t1, t2, template, dim)
188 int t1, t2;
189 entity template;
190 int dim;
191 {
192  int p;
193  return(processor_number(template, dim, t1, &p) ==
194  processor_number(template, dim, t2, &p));
195 }
196 
197 /* every thing should be manageable, i.e.
198  * ??? removed: no star in the dimensions ,
199  * and the width has to be accepted...
200  */
201 static bool
203  entity array,
204  list lpref,
205  list lkref)
206 {
207  list lp = NIL, lk = NIL;
208  int i;
209 
210  for(i=1, lk=lkref, lp=lpref ; lk!=NIL ; lk=CDR(lk), lp=CDR(lp))
211  {
212  tag ta = access_tag(INT(CAR(lk)));
213  Pvecteur v = (Pvecteur) PVECTOR(CAR(lp));
214  Value vs = vect_coeff(TSHIFTV, v),
215  vd = vect_coeff(DELTAV, v),
216  vt = vect_coeff(TEMPLATEV, v);
217  int p = 0,
218  shift = VALUE_TO_INT(vs),
219  dlt = VALUE_TO_INT(vd),
220  t2 = VALUE_TO_INT(vt);
221 
222  if ((ta==not_aligned) ||
223  /*(ta==local_star) ||*/
224  (ta==aligned_star) ||
225  ((ta==aligned_constant) &&
226  (!on_same_proc_p(t2-dlt, t2,
229  ((ta==aligned_shift) &&
230  (shift>DistributionParameterOfArrayDim(array, i, &p))))
231  {
232  debug(5, "message_manageable_p",
233  "returning false for %s, dim %d, access %d\n",
234  entity_name(array), i, ta);
235 
236  return(false);
237  }
238 
239  i++;
240  }
241 
242  if (!block_distributed_p(array)) return(false);
243 
244  /*
245  * here the overlap is accepted, and stored
246  *
247  * ??? this should be done elsewhere, because too much overlap
248  * may be too much memory, allocated... in generate_one_message()?
249  */
250 
251 
252  for(i=1, lk=lkref, lp=lpref ; lk!=NIL ; lk=CDR(lk), lp=CDR(lp))
253  {
254  tag ta = access_tag(INT(CAR(lk)));
255  Value vs = vect_coeff(TSHIFTV, (Pvecteur) PVECTOR(CAR(lp)));
256  int shift = VALUE_TO_INT(vs);
257 
258  if ((ta==aligned_shift) && (shift!=0))
259  set_overlap(array, i, (shift<0)?(0):(1), abs(shift));
260 
261  i++;
262  }
263 
264  return(true); /* accepted! */
265 }
266 
267 /*
268 bool statically_decidable_loops(l)
269 list l;
270 {
271  range r = ((ENDP(l))?(NULL):(loop_range(LOOP(CAR(l)))));
272 
273  return((ENDP(l))?
274  (true):
275  (expression_integer_constant_p(range_lower(r)) &&
276  expression_integer_constant_p(range_upper(r)) &&
277  expression_integer_constant_p(range_increment(r)) &&
278  (HpfcExpressionToInt(range_increment(r))==1) &&
279  statically_decidable_loops(CDR(l))));
280 }
281 */
282 
283 /* generate the call to the dynamic loop bounds computation
284  */
285 static statement
287  entity newlobnd,
288  entity newupbnd,
289  entity oldidxvl,
290  expression lb,
291  expression ub,
292  int an,
293  int dp)
294 {
295  list
296  l = CONS(EXPRESSION, entity_to_expression(newlobnd),
299  CONS(EXPRESSION, lb,
300  CONS(EXPRESSION, ub,
303  NIL)))))));
304 
306 }
307 
308 /* To Kill scalar definitions within the generated code
309  * recognize if only one reference.
310  */
311 static bool hpfc_killed_scalar;
312 
314 statement stat;
315 {
317  i = statement_instruction(stat);
318  expression
320  entity
321  var = entity_undefined;
322 
323  if (!instruction_assign_p(i)) return;
324 
326 
328 
330 
331  debug(5, "hpfc_overlap_kill_unused_scalars_rewrite",
332  "considering definition of %s (statement 0x%x)\n",
333  entity_name(var), stat);
334 
335  if (entity_integer_scalar_p(var) &&
336  load_entity_variable_used(var)==1)
337  {
338  debug(3, "hpfc_overlap_kill_unused_scalars_rewrite",
339  "killing definition of %s (statement 0x%x)\n",
340  entity_name(var), stat);
341 
342  hpfc_killed_scalar = true;
343  statement_instruction(stat) = /* ??? memory leak */
345  }
346 }
347 
348 /* true if one statement was killed
349  */
351 {
352  message_assert("defined", !entity_variable_used_undefined_p());
353 
354  hpfc_killed_scalar = false;
355 
358 
359  return(hpfc_killed_scalar);
360 }
361 
362 /* returns the dimension of reference on which index entity e is used
363  */
364 static int which_array_dimension(r, e)
365 reference r;
366 entity e;
367 {
368  int dim = 1;
369  list li = reference_indices(r);
370  Variable v = (Variable) e;
371 
372  MAP(EXPRESSION, e,
373  {
375 
376  if (normalized_linear_p(n) &&
377  (vect_coeff(v, (Pvecteur)normalized_linear(n)) != 0))
378  return(dim);
379 
380  dim++;
381  },
382  li);
383 
384  return(-1);
385 }
386 
387 static loop
389  entity newindex,
390  expression lower_expression,
391  expression upper_expression)
392 {
393  return(make_loop(newindex,
394  make_range(lower_expression,
395  upper_expression,
396  int_to_expression(1)),
397  statement_undefined, /* statement is not yet defined */
400  NIL));
401 }
402 
403 static void
405  entity_mapping new_indexes,
406  list Ref,
407  list lRef)
408 {
409  list lr = Ref, lkv = lRef;
410 
411  for ( ; (lr!=NIL) ; lr=CDR(lr), lkv=CDR(lkv))
412  {
413  int dim = 1;
414  syntax s = SYNTAX(CAR(lr));
417  list
418  l1 = CONSP(CAR(lkv)),
419  lk = CONSP(CAR(l1)),
420  li = reference_indices(r),
421  lv = CONSP(CAR(CDR(l1))),
422  li2 = NIL;
423 
424  for ( ; (lk!=NIL) ; POP(lk), POP(li), POP(lv))
425  {
426  expression indice = EXPRESSION(CAR(li));
427  Pvecteur v = (Pvecteur) PVECTOR(CAR(lv));
428  access ac = INT(CAR(lk));
429 
430  /* caution: only distributed dimensions indexes are modified
431  * other have to remain untouched...
432  * ??? aligned star is missing
433  */
434  switch (access_tag(ac))
435  {
436  case aligned_shift: /* find the new index of the loop */
437  {
438  Pvecteur vindex = the_index_of_vect(v);
439  entity
440  oldindex = (entity) var_of(vindex),
441  newindex = (entity) GET_ENTITY_MAPPING(new_indexes,
442  oldindex);
443  Value shift = vect_coeff(TSHIFTV, v);
444 
445  if (value_zero_p(shift))
446  {
447  li2 = gen_nconc(li2,
449  entity_to_expression(newindex),
450  NIL));
451  }
452  else
453  {
454  li2 =
455  gen_nconc(li2,
461  entity_to_expression(newindex),
463  NIL));
464  }
465 
466  break;
467  }
468  case aligned_constant: /* compute the local indice */
469  {
470  Value vval = vect_coeff(TEMPLATEV, v);
471  int tval = VALUE_TO_INT(vval);
472 
473  li2 = gen_nconc(li2,
477  dim,
478  tval)),
479  NIL));
480  break;
481  }
482  case aligned_affine:
483  case aligned_star:
484  pips_internal_error("part of that function not implemented yet");
485  break;
486  default: /* ??? nothing is changed */
487  li2 = gen_nconc(li2, CONS(EXPRESSION, indice, NIL));
488  break;
489  }
490  dim++;
491  }
492 
493  reference_indices(r) = li2;
494 
495  ifdebug(8)
496  {
497  fprintf(stderr,
498  "[update_indices_for_local_computation]\nnew reference is:\n");
499  print_reference(r);
500  fprintf(stderr, "\n");
501  }
502 
503  }
504 
505 }
506 
508 entity index;
509 {
510  return(make_assign_statement
511  (entity_to_expression(index),
513  entity_to_expression(index),
514  int_to_expression(1))));
515 }
516 
517 /* bool variable_used_in_statement_p(ent, stat)
518  *
519  * not 0 if ent is referenced in statement stat.
520  * yes, I know, proper effects may be called several
521  * times for the same statement...
522  *
523  * ??? I should have used cumulated/proper effects to be computed on
524  * the statement being generated, but It would not have been as easy
525  * to compute and to use.
526  */
527 static statement
529 
530 static void variable_used_rewrite(r)
531 reference r;
532 {
533  entity v = reference_variable(r);
534 
535  if (bound_entity_variable_used_p(v))
536  update_entity_variable_used(v, load_entity_variable_used(v)+1);
537  else
538  store_entity_variable_used(v, 1);
539 }
540 
541 static void
544 {
545  list ll=lloop, lb=lblocks;
546  instruction i;
547  loop l;
548 
549  init_entity_variable_used();
551 
553 
554  for (; !ENDP(ll); ll=CDR(ll), lb=CDR(lb))
555  {
556  l = LOOP(CAR(ll));
557 
558  MAP(STATEMENT, s,
559  {
560  i = statement_instruction(s);
561 
562  if (!(instruction_loop_p(i) && l==instruction_loop(i)))
563  gen_recurse(s,
565  gen_true,
567 
568  },
569  CONSP(CAR(lb)));
570  }
571 }
572 
574 {
575  close_entity_variable_used();
577 }
578 
579 static bool variable_used_in_statement_p(ent, stat)
580 entity ent;
581 statement stat;
582 {
583  message_assert("current statement", stat==current_variable_used_statement);
584  return bound_entity_variable_used_p(ent);
585 }
586 
588 entity a;
589 {
590  int p = -1, ndim = NumberOfDimension(a), i = 1, n = 0;
591 
592  for (i=1 ; i<=ndim ; i++)
593  if (ith_dim_distributed_p(a, i, &p)) n++;
594 
595  return(n);
596 }
597 
598 /* one of the syntax is chosen from the list. The "larger one".
599  * and the list is given back, the chosen syntax as first element.
600  */
602 list *pls;
603 {
604  list cls = *pls, nls = NIL;
605  syntax chosen = SYNTAX(CAR(cls));
606  int chosen_distribution =
609 
610  MAP(SYNTAX, current,
611  {
612  int current_distribution =
615 
616  if (current_distribution > chosen_distribution)
617  {
618  nls = CONS(SYNTAX, chosen, nls);
619  chosen = current;
620  chosen_distribution = current_distribution;
621  }
622  else
623  nls = CONS(SYNTAX, current, nls);
624  },
625  CDR(cls));
626 
627  gen_free_list(cls);
628  *pls = CONS(SYNTAX, chosen, nls);
629 
630  debug(7, "choose_one_syntax_in_references_list",
631  "reference to %s chosen, %d dimensions\n",
633  chosen_distribution);
634 
635  return(chosen);
636 }
637 
638 static statement
640  list lold,
641  list lnew,
642  list lbl,
643  entity_mapping new_indexes,
644  entity_mapping old_indexes,
645  statement innerbody)
646 {
647  entity index, oldindexvalue;
648  loop oldloop, newloop;
649  list l, lnew_loop = NIL, lnew_body = NIL;
650  bool compute_index = false;
651 
652  if (ENDP(lold))
653  return(innerbody);
654 
655  oldloop = LOOP(CAR(lold));
656  newloop = LOOP(CAR(lnew));
657 
658  index = loop_index(oldloop);
659  oldindexvalue = (entity) GET_ENTITY_MAPPING(old_indexes, index);
660  lnew_body = CONS(STATEMENT,
661  make_loop_nest_for_overlap(CDR(lold), CDR(lnew), CDR(lbl),
662  new_indexes, old_indexes,
663  innerbody),
664  NIL);
665 
666  /* ??? should also look in lbl */
667  compute_index = (oldindexvalue!=(entity)HASH_UNDEFINED_VALUE) &&
668  variable_used_in_statement_p(index, innerbody);
669 
670  /* if the index value is needed, the increment is added
671  */
672  if (compute_index)
673  lnew_body = CONS(STATEMENT, make_increment_statement(index),
674  lnew_body);
675 
676  loop_body(newloop) = make_block_statement(lnew_body);
677  lnew_loop = CONS(STATEMENT,
679  newloop)),
680  NIL);
681 
682  /* i = initial_old_value
683  * DO i' = ...
684  * i = i + 1
685  * body
686  * ENDDO
687  */
688 
689  if (compute_index)
690  lnew_loop =
691  CONS(STATEMENT,
693  entity_to_expression(oldindexvalue)),
694  lnew_loop);
695 
696  /* copy the non perfectly nested parts if needed
697  */
698  l = CONSP(CAR(lbl));
699  if (!ENDP(l))
700  {
701  statement
702  s;
704  i;
705  list
706  lpre = NIL,
707  lpost = NIL;
708  bool
709  pre = true;
710 
711  for(; !ENDP(l); l=CDR(l))
712  {
713  s = STATEMENT(CAR(l));
714  i = statement_instruction(s);
715 
716  /* switch from pre to post.
717  */
718  if (instruction_loop_p(i) && instruction_loop(i)==oldloop)
719  pre = false;
720  else
721  if (pre)
722  lpre = CONS(STATEMENT, copy_statement(s), lpre);
723  else
724  lpost = CONS(STATEMENT, copy_statement(s), lpost);
725  }
726 
727  /* the swith must have been encountered */
728  assert(!pre);
729 
730  lnew_loop = gen_nconc(gen_nreverse(lpre),
731  gen_nconc(lnew_loop,
732  gen_nreverse(lpost)));
733  }
734 
735  return(make_block_statement(lnew_loop));
736 }
737 
738 static bool
740  statement innerbody,
741  statement *pstat,
742  syntax the_computer_syntax,
743  list Wa,
744  list Ra,
745  list Ro,
746  list lWa,
747  list lRa,
748  list lRo)
749 {
750  reference the_computer_reference = syntax_reference(the_computer_syntax);
751  entity array = reference_variable(the_computer_reference);
752  int an = load_hpf_number(array);
754  new_indexes = MAKE_ENTITY_MAPPING(),
755  old_indexes = MAKE_ENTITY_MAPPING();
756  list boundcomp = NIL, newloops = NIL;
757  statement newnest = NULL;
758  range rg;
759  expression lb, ub;
760  entity index, newindex, newlobnd, newupbnd, oldidxvl;
761  loop nl;
762  int p, dim;
763 
764  MAP(LOOP, l,
765  {
766  index = loop_index(l);
767  dim = which_array_dimension(the_computer_reference, index);
768 
769  if (ith_dim_distributed_p(array, dim, &p))
770  {
771  statement bc;
772 
773  /* new bounds to compute, and so on */
774  rg = loop_range(l);
775  lb = copy_expression(range_lower(rg));
776  ub = copy_expression(range_upper(rg));
777 
786  AddEntityToCurrentModule(newindex);
787  AddEntityToCurrentModule(newlobnd);
788  AddEntityToCurrentModule(newupbnd);
789  AddEntityToCurrentModule(oldidxvl);
790 
792  (newlobnd, newupbnd, oldidxvl, lb, ub, an, p);
793 
794  /* constant new loop bounds are computed on entry
795  * in the subroutine.
796  */
800  else
801  boundcomp = gen_nconc(boundcomp, CONS(STATEMENT, bc, NIL));
802 
803  newloops =
804  gen_nconc(newloops,
805  CONS(LOOP,
806  make_loop_skeleton(newindex,
807  entity_to_expression(newlobnd),
808  entity_to_expression(newupbnd)),
809  NIL));
810 
811  SET_ENTITY_MAPPING(new_indexes, index, newindex);
812  SET_ENTITY_MAPPING(old_indexes, index, oldidxvl);
813  }
814  else
815  {
816  nl = make_loop(loop_index(l),
817  loop_range(l),
819  loop_label(l),
821  NIL);
822 /* ??? there is a core dump on the second free, when executed, in test 37~;
823  free_execution(loop_execution(l));
824  free_loop(l);
825 */
826  newloops = gen_nconc(newloops, CONS(LOOP, nl, NIL));
827  }
828  },
829  lloop);
830 
831  update_indices_for_local_computation(new_indexes, Wa, lWa);
832  update_indices_for_local_computation(new_indexes, Ra, lRa);
833  update_indices_for_local_computation(new_indexes, Ro, lRo);
834 
835  /* and now generates the code...
836  */
838 
839  if (hpfc_overlap_kill_unused_scalars(innerbody))
840  {
843  }
844 
845  newnest = make_loop_nest_for_overlap(lloop, newloops, lblocks,
846  new_indexes, old_indexes,
847  innerbody);
849 
850 
851  (*pstat) = make_block_statement(gen_nconc(boundcomp,
852  CONS(STATEMENT, newnest,
853  NIL)));
854 
855  return(true);
856 }
857 
858 /* must clear everything before returning in Overlap_Analysis...
859  */
860 #define RETURN(x) \
861 { pips_debug(9, "returning %d from line %d\n", x, __LINE__);\
862  gen_free_list(Wa); gen_free_list(lWa); gen_free_list(Ra);\
863  gen_free_list(lRa); gen_free_list(Ro); gen_free_list(lRo);\
864  gen_free_list(Rrt); gen_free_list(lblocks); gen_free_list(lloop);\
865  gen_free_list(W); gen_free_list(R); gen_free_list(lw); gen_free_list(lr);\
866  reset_hpfc_current_statement(); reset_current_loops(); return x;}
867 
868 /* check conditions and compile...
869  */
870 bool Overlap_Analysis(stat, pstat)
871 statement stat, *pstat;
872 {
873  list lw = NIL, lr = NIL, Ra = NIL, Ro = NIL, Rrt = NIL,
874  lWa = NIL, lRa = NIL, lRo = NIL, W = NIL, Wa = NIL,
875  Wrt = NIL, lvect = NIL, lkind = NIL, R=NIL;
876  syntax the_computer_syntax = syntax_undefined;
877  reference the_computer_reference = reference_undefined;
878  statement innerbody, messages_stat, newloopnest;
879  bool computer_is_written = true;
880 
881  DEBUG_STAT(9, "considering statement", stat);
882 
884  set_current_loops(stat);
885 
886  lblocks = NIL,
887  lloop = NIL;
888  innerbody = parallel_loop_nest_to_body(stat, &lblocks, &lloop);
889 
890  FindRefToDistArrayInStatement(stat, &lw, &lr);
891 
892  /* keeps only written references of which dimensions are block distributed,
893  * and indices simple enough (=> normalization of loops may be usefull).
894  * ??? bug: should also search for A(i,i) things that are forbidden...
895  */
896  MAP(SYNTAX, s,
897  {
900 
901  if ((block_distributed_p(array)) &&
902  (simple_indices_p(r)) && (!replicated_p(array)))
903  W = CONS(SYNTAX, s, W);
904  else
905  Wrt = CONS(SYNTAX, s, Wrt);
906  },
907  lw);
908 
909  pips_debug(9, "choosing computer\n");
910 
911  if (W) /* ok distributed variable written ! */
912  {
913  the_computer_syntax = choose_one_syntax_in_references_list(&W);
914  the_computer_reference = syntax_reference(the_computer_syntax);
915  Wa = CONS(SYNTAX, the_computer_syntax, NIL);
916  }
917  else /* must chose the computer among read references! */
918  {
919  computer_is_written = false;
920 
921  MAP(SYNTAX, s,
922  {
925 
926  if ((block_distributed_p(array)) &&
927  (simple_indices_p(r)) && (!replicated_p(array)))
928  R = CONS(SYNTAX, s, R);
929  },
930  lr);
931 
932  if (R)
933  {
934  the_computer_syntax = choose_one_syntax_in_references_list(&R);
935  the_computer_reference = syntax_reference(the_computer_syntax);
936  Ra = CONS(SYNTAX, the_computer_syntax, NIL);
937  }
938  else
939  RETURN(false);
940  }
941 
942  if (!align_check(the_computer_reference,
943  the_computer_reference, &lvect, &lkind))
944  pips_internal_error("no self alignment!");
945 
946  if (computer_is_written)
947  lWa = CONS(LIST, CONS(LIST, lkind, CONS(LIST, lvect, NIL)), NIL);
948  else
949  lRa = CONS(LIST, CONS(LIST, lkind, CONS(LIST, lvect, NIL)), NIL);
950 
951  pips_debug(9, "checking alignments\n");
952 
953  MAP(SYNTAX, s,
954  {
956  if (the_computer_reference==r)
957  continue;
958  if (align_check(the_computer_reference, r, &lvect, &lkind))
959  {
960  if (aligned_p(the_computer_reference, r, lvect, lkind))
961  {
962  Wa = gen_nconc(Wa, CONS(SYNTAX, s, NIL));
963  lWa = gen_nconc(lWa, CONS(LIST,
964  CONS(LIST, lkind,
965  CONS(LIST, lvect, NIL)),
966  NIL));
967  }
968  else /* ??? what about loop splitting */
969  {
970  Wrt = gen_nconc(Wrt, CONS(SYNTAX, s, NIL));
972  gen_free_list(lkind); /* ??? memory leak */
973  }
974  }
975  else
976  {
977  Wrt = gen_nconc(Wrt, CONS(SYNTAX, s, NIL));
979  gen_free_list(lkind); /* ??? memory leak */
980  }
981  },
982  W);
983 
984  pips_debug(5, "Wa length is %zd (%zd), Wrt lenght is %zd\n",
985  gen_length(Wa), gen_length(lWa), gen_length(Wrt));
986 
987  if (gen_length(Wrt)!=0)
988  RETURN(false);
989 
990  /* Now, we have the following situation:
991  * Wa: set of aligned written refs, the first of which is ``the'' ref.
992  */
993  MAP(SYNTAX, s,
994  {
997  list lvect = NIL;
998  list lkind = NIL;
999 
1000  if (the_computer_reference==r) continue;
1001 
1002  pips_debug(6, "dealing with reference of array %s\n",
1003  entity_name(array));
1004 
1005  ifdebug(6)
1006  {
1007  fprintf(stderr, "[Overlap_Analysis]\nreference is:\n");
1008  print_reference(r);
1009  fprintf(stderr, "\n");
1010  }
1011 
1012  if (align_check(the_computer_reference, r, &lvect, &lkind))
1013  {
1014  if (aligned_p(the_computer_reference, r, lvect, lkind))
1015  {
1016  Ra = gen_nconc(Ra, CONS(SYNTAX, s, NIL));
1017  lRa = gen_nconc(lRa, CONS(LIST,
1018  CONS(LIST, lkind,
1019  CONS(LIST, lvect, NIL)),
1020  NIL));
1021  }
1022  else
1023  if (message_manageable_p(array, lvect, lkind))
1024  {
1025  Ro = gen_nconc(Ro, CONS(SYNTAX, s, NIL));
1026  lRo = gen_nconc(lRo, CONS(LIST,
1027  CONS(LIST, lkind,
1028  CONS(LIST, lvect, NIL)),
1029  NIL));
1030  }
1031  else
1032  {
1033  Rrt = gen_nconc(Rrt, CONS(SYNTAX, s, NIL));
1035  gen_free_list(lkind);
1036  }
1037  }
1038  else
1039  {
1040  Rrt = gen_nconc(Rrt, CONS(SYNTAX, s, NIL));
1042  gen_free_list(lkind);
1043  }
1044  },
1045  lr);
1046 
1047  debug(5, "Overlap_Analysis",
1048  "Ra length is %d, Ro length is %d, Rrt lenght is %d\n",
1049  gen_length(Ra), gen_length(Ro), gen_length(Rrt));
1050 
1051  if (gen_length(Rrt)!=0)
1052  RETURN(false);
1053 
1054  /* here is the situation now:
1055  *
1056  * Wa set of aligned references written,
1057  * Ra set of aligned references read,
1058  * Ro set of nearly aligned references that suits the overlap analysis
1059  */
1060 
1061  /* messages handling
1062  */
1063  messages_stat = ((gen_length(Ro)>0)?
1064  (messages_handling(Ro, lRo)):
1066 
1067  /* generate the local loop for every processor, given the global loop
1068  * bounds. The former indexes have to be computed, and the loops are
1069  * based upon new indexes, of which names have to be propagated in the
1070  * body of the loop. This generation is to be based on the normalized
1071  * form computed for every references of Ro, but it is direct for
1072  * Ra and Wa, since new declarations implied that the alignment is
1073  * performed for distributed indices. Not distributed dimensions
1074  * indices have not to be touched, (at least if no new declarations are
1075  * the common case)
1076  */
1078  (innerbody, &newloopnest, the_computer_syntax,
1079  Wa, Ra, Ro, lWa, lRa, lRo))
1080  RETURN(false);
1081 
1082  DEBUG_STAT(9, entity_name(node_module), newloopnest);
1083 
1084  (*pstat) =
1086  (CONS(STATEMENT, messages_stat,
1087  CONS(STATEMENT,
1088  loop_nest_guard(newloopnest,
1089  the_computer_reference,
1090  CONSP(CAR(CONSP(CAR(computer_is_written? lWa: lRa)))),
1091  CONSP(CAR(CDR(CONSP(CAR(computer_is_written? lWa: lRa)))))),
1092  NIL)));
1093 
1094  DEBUG_STAT(8, entity_name(node_module), *pstat);
1095 
1096  RETURN(true);
1097 }
1098 
1099 /* That is all
1100  */
execution make_execution(enum execution_utype tag, void *val)
Definition: ri.c:838
loop make_loop(entity a1, range a2, statement a3, entity a4, execution a5, list a6)
Definition: ri.c:1301
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
statement copy_statement(statement p)
STATEMENT.
Definition: ri.c:2186
instruction make_instruction(enum instruction_utype tag, void *val)
Definition: ri.c:1166
range make_range(expression a1, expression a2, expression a3)
Definition: ri.c:2041
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
#define aligned_shift
#define access
#define not_aligned
#define aligned_star
#define aligned_affine
#define aligned_constant
#define access_tag(a)
bool local_integer_constant_expression(expression e)
true is the expression is locally constant, that is in the whole loop nest, the reference is not writ...
Definition: align-checker.c:64
bool align_check(reference r1, reference r2, list *plvect, list *plkind)
computes the shift vector that links the two references, true if every thing is ok,...
#define value_pos_p(val)
#define VALUE_TO_INT(val)
#define value_zero_p(val)
int Value
#define value_abs(val)
@ INT
Definition: atomic.c:48
static hash_table Ref
Refs maps each statement to the effects it references.
Definition: chains.c:96
statement parallel_loop_nest_to_body(statement loop_nest, list *pblocks, list *ploops)
bool entity_loop_index_p(entity e)
void set_current_loops(statement obj)
void FindRefToDistArrayInStatement(statement obj, list *lwp, list *lrp)
static statement inner_body
entity node_module
Definition: compiler.c:47
void vect_debug(Pvecteur v)
constraint.c
Definition: constraint.c:43
#define LIST(x)
Definition: genC.h:93
#define CONSP(x)
Definition: genC.h:88
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
statement make_block_statement(list)
Make a block statement from a list of statement.
Definition: statement.c:616
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
Definition: statement.c:597
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
instruction make_continue_instruction()
Creates a CONTINUE instruction, that is the FORTRAN nop, the ";" in C or the "pass" in Python for exa...
Definition: instruction.c:79
bool instruction_assign_p(instruction i)
Test if an instruction is an assignment.
Definition: instruction.c:164
#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
#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
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
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#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
statement make_assign_statement(expression, expression)
Definition: statement.c:583
statement make_continue_statement(entity)
Definition: statement.c:953
#define alignment_undefined
Definition: hpf.h:108
#define alignment_rate(x)
Definition: hpf.h:138
@ is_hpf_newdecl_delta
Definition: hpf_private.h:669
@ is_hpf_newdecl_gamma
Definition: hpf_private.h:668
int template_cell_local_mapping(entity array, int dim, int tc)
int template_cell_local_mapping(array, dim, tc)
Definition: hpfc-util.c:532
int DistributionParameterOfArrayDim(entity array, int dim, int *pprocdim)
Definition: hpfc-util.c:472
int HpfcExpressionToInt(expression e)
HpfcExpressionToInt(e)
Definition: hpfc-util.c:569
bool ith_dim_distributed_p(entity array, int i, int *pprocdim)
whether a dimension is distributed or not.
Definition: hpfc-util.c:160
bool replicated_p(entity e)
replicated_p
Definition: hpfc-util.c:96
int processor_number(entity template, int tdim, int tcell, int *pprocdim)
int processor_number(template, tdim, tcell, pprocdim)
Definition: hpfc-util.c:492
int template_dimension_of_array_dimension(entity array, int dim)
Definition: hpfc-util.c:448
tag new_declaration_tag(entity array, int dim)
Definition: declarations.c:229
void set_overlap(entity ent, int dim, int side, int width)
set the overlap value for entity ent, on dimension dim, dans side side to width, which must be a posi...
Definition: declarations.c:713
#define FindArrayDimAlignmentOfArray(array, dim)
#define TEMPLATEV
Definition: defines-local.h:80
#define array_to_template(array)
#define TSHIFTV
Definition: defines-local.h:81
#define LOOP_BOUNDS
#define DELTAV
??? very beurk!
Definition: defines-local.h:79
#define DEBUG_STAT(D, W, S)
#define PVECTOR(v)
Definition: defines-local.h:72
void hpfc_add_ahead_of_node_code(statement s)
Definition: hpfc.c:404
entity hpfc_name_to_entity(const char *)
Definition: run-time.c:817
void set_hpfc_current_statement(statement)
Pvecteur the_index_of_vect(Pvecteur)
message-utils.c
Definition: message-utils.c:37
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
statement messages_handling(list, list)
messages.c
Definition: messages.c:724
statement loop_nest_guard(statement, reference, list, list)
intptr_t load_hpf_number(entity)
int vect_size(Pvecteur v)
package vecteur - reductions
Definition: reductions.c:47
#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_internal_error
Definition: misc-local.h:149
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
#define GET_ENTITY_MAPPING(map, ent)
Definition: newgen-local.h:71
#define MAKE_ENTITY_MAPPING()
Definition: newgen-local.h:65
#define SET_ENTITY_MAPPING(map, ent, val)
Definition: newgen-local.h:69
#define assert(ex)
Definition: newgen_assert.h:41
#define message_assert(msg, ex)
Definition: newgen_assert.h:47
#define HASH_UNDEFINED_VALUE
value returned by hash_get() when the key is not found; could also be called HASH_KEY_NOT_FOUND,...
Definition: newgen_hash.h:56
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
#define UU
Definition: newgen_types.h:98
static int number_of_distributed_dimensions(entity a)
Definition: o-analysis.c:587
static syntax choose_one_syntax_in_references_list(list *pls)
one of the syntax is chosen from the list.
Definition: o-analysis.c:601
static statement make_increment_statement(entity index)
Definition: o-analysis.c:507
static int which_array_dimension(reference r, entity e)
returns the dimension of reference on which index entity e is used
Definition: o-analysis.c:364
static bool generate_optimized_code_for_loop_nest(statement innerbody, statement *pstat, syntax the_computer_syntax, list Wa, list Ra, list Ro, list lWa, list lRa, list lRo)
Definition: o-analysis.c:739
static loop make_loop_skeleton(entity newindex, expression lower_expression, expression upper_expression)
Definition: o-analysis.c:388
static list lblocks
Overlap Analysis Module for HPFC.
Definition: o-analysis.c:38
static statement statement_compute_bounds(entity newlobnd, entity newupbnd, entity oldidxvl, expression lb, expression ub, int an, int dp)
generate the call to the dynamic loop bounds computation
Definition: o-analysis.c:286
static bool message_manageable_p(entity array, list lpref, list lkref)
every thing should be manageable, i.e.
Definition: o-analysis.c:202
static bool simple_indices_p(reference r)
true if indices are constants or index
Definition: o-analysis.c:64
#define RETURN(x)
must clear everything before returning in Overlap_Analysis...
Definition: o-analysis.c:860
static void initialize_variable_used_map_for_current_loop_nest(statement inner_body)
Definition: o-analysis.c:542
static bool on_same_proc_p(int t1, int t2, entity template, int dim)
true if the given template elements on the specified dimension are mapped on the same processor.
Definition: o-analysis.c:187
bool Overlap_Analysis(statement stat, statement *pstat)
check conditions and compile...
Definition: o-analysis.c:870
static void close_variable_used_map_for_statement()
Definition: o-analysis.c:573
bool block_distributed_p(entity array)
true if there is no cyclic distribution for the array
Definition: o-analysis.c:44
static bool variable_used_in_statement_p(entity ent, statement stat)
Definition: o-analysis.c:579
static statement make_loop_nest_for_overlap(list lold, list lnew, list lbl, entity_mapping new_indexes, entity_mapping old_indexes, statement innerbody)
Definition: o-analysis.c:639
static void update_indices_for_local_computation(entity_mapping new_indexes, list Ref, list lRef)
Definition: o-analysis.c:404
static void hpfc_overlap_kill_unused_scalars_rewrite(statement stat)
Definition: o-analysis.c:313
static bool aligned_p(reference r1, reference r2, list lvref, list lkref)
true if references are aligned or, for constants, on the same processor...
Definition: o-analysis.c:144
static void variable_used_rewrite(reference r)
Definition: o-analysis.c:530
static bool hpfc_overlap_kill_unused_scalars(statement stat)
true if one statement was killed
Definition: o-analysis.c:350
static bool hpfc_killed_scalar
To Kill scalar definitions within the generated code recognize if only one reference.
Definition: o-analysis.c:311
static statement current_variable_used_statement
bool variable_used_in_statement_p(ent, stat)
Definition: o-analysis.c:528
static list lloop
Definition: o-analysis.c:38
void print_reference(reference r)
Definition: expression.c:142
#define MINUS_OPERATOR_NAME
#define PLUS_OPERATOR_NAME
entity entity_empty_label(void)
Definition: entity.c:1105
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
bool expression_integer_constant_p(expression e)
Definition: expression.c:2417
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
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
expression Value_to_expression(Value v)
added interface for linear stuff.
Definition: expression.c:1251
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
basic MakeBasic(int)
END_EOLE.
Definition: type.c:128
entity make_new_scalar_variable(entity, basic)
Definition: variable.c:741
void AddEntityToCurrentModule(entity)
Add a variable entity to the current module declarations.
Definition: variable.c:260
int NumberOfDimension(entity)
Definition: size.c:588
bool entity_integer_scalar_p(entity)
for variables (like I), not constants (like 1)! use integer_constant_p() for constants
Definition: variable.c:1130
#define loop_body(x)
Definition: ri.h:1644
@ is_basic_int
Definition: ri.h:571
#define LOOP(x)
LOOP.
Definition: ri.h:1606
#define syntax_reference(x)
Definition: ri.h:2730
#define reference_undefined
Definition: ri.h:2302
#define normalized_complex_p(x)
Definition: ri.h:1782
#define normalized_linear_p(x)
Definition: ri.h:1779
#define instruction_loop_p(x)
Definition: ri.h:1518
#define reference_variable(x)
Definition: ri.h:2326
#define range_upper(x)
Definition: ri.h:2290
#define instruction_loop(x)
Definition: ri.h:1520
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define reference_domain
newgen_range_domain_defined
Definition: ri.h:338
#define entity_undefined
Definition: ri.h:2761
#define expression_undefined
Definition: ri.h:1223
@ is_instruction_loop
Definition: ri.h:1471
#define entity_name(x)
Definition: ri.h:2790
#define expression_normalized(x)
Definition: ri.h:1249
#define reference_indices(x)
Definition: ri.h:2328
#define loop_label(x)
Definition: ri.h:1646
#define range_lower(x)
Definition: ri.h:2288
#define statement_instruction(x)
Definition: ri.h:2458
#define syntax_undefined
Definition: ri.h:2676
#define instruction_call(x)
Definition: ri.h:1529
#define loop_range(x)
Definition: ri.h:1642
@ is_execution_sequential
Definition: ri.h:1189
#define call_arguments(x)
Definition: ri.h:711
#define normalized_linear(x)
Definition: ri.h:1781
#define expression_syntax(x)
Definition: ri.h:1247
#define loop_index(x)
Definition: ri.h:1640
#define statement_undefined
Definition: ri.h:2419
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
#define SYNTAX(x)
SYNTAX.
Definition: ri.h:2670
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 ...
#define ifdebug(n)
Definition: sg.c:47
static list lvect
static entity array
GENERIC_LOCAL_FUNCTION(directives, step_directives)
Copyright 2007, 2008, 2009 Alain Muller, Frederique Silber-Chaussumier.
static size_t current
Definition: string.c:115
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
Variable var
Definition: vecteur-local.h:90
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
#define abs(v)
Definition: syntax-local.h:48
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
struct Svecteur * Pvecteur
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 var_of(varval)
Value vect_coeff(Variable var, Pvecteur vect)
Variable vect_coeff(Variable var, Pvecteur vect): coefficient de coordonnee var du vecteur vect —> So...
Definition: unaires.c:228