PIPS
comEngine_generate_procCode.c
Go to the documentation of this file.
1 /*
2 
3  $Id: comEngine_generate_procCode.c 23495 2018-10-24 09:19:47Z 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 /*
28 This file contains functions used to generate the MMCDs generation code
29  */
30 
31 #include <stdio.h>
32 #include <ctype.h>
33 
34 #include "genC.h"
35 #include "linear.h"
36 #include "ri.h"
37 #include "effects.h"
38 
39 #include "resources.h"
40 
41 #include "misc.h"
42 #include "ri-util.h"
43 #include "prettyprint.h"
44 #include "effects-util.h"
45 
46 #include "text-util.h"
47 #include "properties.h"
48 
49 
50 #include "ray_dte.h"
51 #include "sommet.h"
52 #include "sg.h"
53 #include "polyedre.h"
54 
55 #include "phrase_tools.h"
56 
57 #include "effects-generic.h"
58 #include "effects-simple.h"
59 #include "effects-convex.h"
60 
61 #include "phrase_distribution.h"
62 #include "comEngine.h"
64 #include "phrase.h"
65 
66 // This hash_table is used to store the fifo
67 // used at a given point of the algorithm
69 
70 // This is the variable that holds
71 // the current step value
73 
74 // This hash_table associates a reference to its
75 // old fifo value. The old fifo value was associated to the
76 // reference during the analysis phase.
78 
79 static list make_mmcd_stats_from_ref(statement stat, list lSupportedRef, hash_table htOffset,
80  entity transferSize, entity newOuterInd, statement innerStat);
81 
82 /*
83 This function return true if the reference whose indices are lRefDim is
84 supported and, in this case, the value of the offset is put in retVal.
85  */
86 static bool get_final_offset(list lRefDim, intptr_t offset, int rank, intptr_t * retVal)
87 {
88  bool fort_org = get_bool_property("SIMD_FORTRAN_MEM_ORGANISATION");
89 
90  int i = 0;
91  int ind;
92 
93  intptr_t finalOffset = 1;
94 
95  for(i = 0; i < (int) gen_length(lRefDim); i++)
96  {
97  if(fort_org)
98  {
99  ind = i;
100  }
101  else
102  {
103  ind = gen_length(lRefDim) - i - 1;
104  }
105 
106  if(ind == rank)
107  {
108  break;
109  }
110 
111  dimension curDim = DIMENSION(gen_nth(ind, lRefDim));
112 
113  expression lowerExp = dimension_lower(curDim);
114  expression upperExp = dimension_upper(curDim);
115 
116  if(!integer_constant_expression_p(lowerExp) ||
118  {
119  return false;
120  }
121 
122  int lower = integer_constant_expression_value(lowerExp);
123  int upper = integer_constant_expression_value(upperExp);
124 
125  pips_assert("lower < upper", lower < upper);
126 
127  finalOffset = finalOffset * (upper - lower + 1);
128  }
129 
130  *retVal = finalOffset * offset;
131 
132  return true;
133 }
134 
135 /*
136 This function return true if reference ref is
137 supported and, in this case, it updates the hash_table htOffset.
138  */
139 static bool supported_ref_p(reference ref, entity index, hash_table htOffset)
140 {
141  bool success = true;
142  int offset = 0;
143  int rank = 0;
144 
145  //printf("supported_ref_p \n");
146  //print_reference(ref);printf("\n");
147 
148  MAP(EXPRESSION, ind,
149  {
151 
152  list indRefList = NIL;
153 
155  {
157 
158  int curOffset = vect_coeff((Variable) index, vect);
159 
160  if(curOffset != 0)
161  {
162  if(offset != 0)
163  {
164  success = false;
165  }
166 
167  offset = curOffset;
168  }
169  }
170  else
171  {
172  success = false;
173  }
174 
175  if(offset == 0)
176  {
177  rank++;
178  }
179 
180  gen_free_list(indRefList);
181 
182  }, reference_indices(ref));
183 
184  if(success)
185  {
187 
188  pips_assert("ref type is not variable", type_variable_p(refType));
189 
190  list lRefDim = variable_dimensions(type_variable(refType));
191 
192  intptr_t finalOffset;
193 
194  if(!get_final_offset(lRefDim, offset, rank, &finalOffset))
195  {
196  return false;
197  }
198 
199  //printf("finalOffset %d\n", finalOffset);
200  //printf("\n");
201 
202  pips_assert("finalOffset > 0", (finalOffset > 0));
203 
204  hash_put(htOffset, ref, (void*)finalOffset);
205  }
206 
207  return success;
208 }
209 
210 /*
211 This function is used by has_call_stat_inside
212  */
213 static bool has_call_stat_inside_flt(statement stat, bool * bHasCallStat)
214 {
215  instruction instr = statement_instruction(stat);
216 
217  switch(instruction_tag(instr))
218  {
219  case is_instruction_loop:
222  {
223  return false;
224  break;
225  }
226 
228  case is_instruction_test:
229  {
230  return true;
231  break;
232  }
233  case is_instruction_call:
234  {
235  *bHasCallStat = true;
236  break;
237  }
238  default:
239  {
240  pips_internal_error("unsupported tag");
241  break;
242  }
243  }
244 
245  return false;
246 }
247 
248 /*
249 This function is used by has_call_stat_inside
250  */
252  _UNUSED_ statement stat,
253  _UNUSED_ bool * bHasCallStat)
254 {
255 }
256 
257 /*
258 This function returns true if statement stat contains a call statement.
259  */
261 {
262  bool bHasCallStat = false;
263 
264  gen_context_recurse(stat, &bHasCallStat, statement_domain,
266 
267  return bHasCallStat;
268 }
269 
270 /*
271 This function returns the real fifo number from the old fifo number
272 fifoNum.
273  */
275 {
276  static intptr_t gCurFifoCounter = 1;
277 
278  //printf("get_realFifoNum %d\n", fifoNum);
279 
280  // fifoNum value can be -1, if we want to increment
281  // gCurFifoCounter with 1
282  if(fifoNum < 0)
283  {
284  intptr_t newFifoNum = gCurFifoCounter;
285 
286  gCurFifoCounter += 1;
287 
288  return newFifoNum;
289  }
290 
291  intptr_t realFifoNum = (intptr_t)hash_get(gRealFifo, (void *)fifoNum);
292 
293  // If no realFifoNum was associated with fifoNum,
294  // then create a new realFifoNum
295  if(realFifoNum == (intptr_t)HASH_UNDEFINED_VALUE)
296  {
297  realFifoNum = gCurFifoCounter;
298 
299  hash_put(gRealFifo, (void *)fifoNum, (void *)realFifoNum);
300 
301  HASH_MAP(ref1, fifo1,
302  {
303  if((intptr_t)fifo1 == (intptr_t)fifoNum)
304  {
305  hash_put(gRefToHREFifo, ref1, (void *)realFifoNum);
306  }
307  }, gOldRefToHREFifo);
308 
309  // Get the number of fifo that has to be allocated for this
310  // realFifoNum
311  intptr_t inc = (intptr_t)hash_get(gRefToFifoOff, (void *)fifoNum);
312 
313  if(inc == (intptr_t)HASH_UNDEFINED_VALUE)
314  {
315  inc = 1;
316  }
317 
318  gCurFifoCounter += inc;
319  }
320 
321  return realFifoNum;
322 }
323 
324 /*
325 This function get the toggle entity associated to reference curRef
326  */
327 static entity get_toggleEnt_from_ref(reference curRef, list lToggleEnt)
328 {
329  void* fifoNum = hash_get(gRefToFifo, curRef);
330 
331  pips_assert("fifoNum != HASH_UNDEFINED_VALUE",
332  fifoNum != HASH_UNDEFINED_VALUE);
333 
334  intptr_t numOfFifo = (intptr_t)hash_get(gRefToFifoOff, fifoNum);
335 
336  pips_assert("(numOfFifo == 2) || (numOfFifo == 3)",
337  (numOfFifo == 2) || (numOfFifo == 3));
338 
339  entity toggleEnt = entity_undefined;
340 
341  MAP(ENTITY, curEnt,
342  {
343  intptr_t curInc = (intptr_t)hash_get(gToggleToInc, curEnt);
344 
345  if(curInc == numOfFifo)
346  {
347  toggleEnt = curEnt;
348  break;
349  }
350 
351  }, lToggleEnt);
352 
353  pips_assert("toggleEnt != entity_undefined",
354  toggleEnt != entity_undefined);
355 
356  return toggleEnt;
357 }
358 
360  expression hreBuff,
361  expression refExp,
362  expression offExp,
363  expression countExp)
364 {
365  expression stepExp;
366 
367  if(!strcmp(name, GEN_STORE_MMCD))
368  {
372  NULL);
373 
374  stepExp =
376  addArg));
377  }
378  else
379  {
380  stepExp = entity_to_expression(gStepEnt);
381  }
382 
384  stepExp,
385  hreBuff,
386  refExp,
387  offExp,
388  countExp,
389  NULL);
390 
391  statement newStat =
393  arg));
394 
395  return newStat;
396 }
397 
398 /*
399 This function generates one Load an Store MMCD statement associated
400 to curRef
401  */
403  expression count, bool bRead,
404  list lToggleEnt)
405 {
406  statement newStat = statement_undefined;
407 
408  string name = NULL;
409 
410  intptr_t fifoNum = (intptr_t)hash_get(gRefToFifo, curRef);
411 
412  pips_assert("fifoNum != HASH_UNDEFINED_VALUE",
413  fifoNum != (intptr_t)HASH_UNDEFINED_VALUE);
414 
415  // Get the fifo number
416  int realFifoNum = get_realFifoNum(fifoNum);
417 
419 
420  // If the toggle entity list is NIL, then realFifoNum is
421  // the fifo Number to use
422  if(lToggleEnt == NIL)
423  {
424  hreBuff = int_to_expression(realFifoNum);
425  }
426  // else, ...
427  else
428  {
429  printf("generate_mmcd_stat_from_ref 1\n");
430  print_reference(curRef);printf("\n");
431 
432  // Get the toggle entity
433  entity toggleEnt = get_toggleEnt_from_ref(curRef, lToggleEnt);
434 
436  int_to_expression(realFifoNum),
437  entity_to_expression(toggleEnt),
438  NULL);
439 
440  // Add the toggle entity and the fifo number
441  hreBuff =
443  addArg));
444  }
445 
446  if(bRead)
447  {
448  name = strdup(GEN_LOAD_MMCD);
449  }
450  else
451  {
452  name = strdup(GEN_STORE_MMCD);
453  }
454 
455  // Generate the statement
456  newStat =
457  make_mmcd_load_store_stat(name, hreBuff,
460 
461  return newStat;
462 }
463 
464 /*
465 This function generates one Load an Store MMCD statement associated
466 to lRef
467  */
468 static void generate_mmcd_stats_from_ref(list lRef, hash_table htOffset,
469  expression count, list lToggleEnt,
470  list * lReadStats, list * lWriteStats)
471 {
472  list lReadDone = NIL;
473  list lWriteDone = NIL;
474 
475  intptr_t offset = 0;
476 
477  MAP(REFERENCE, curRef,
478  {
479  if(htOffset != NULL)
480  {
481  offset = (intptr_t)hash_get(htOffset, curRef);
482 
483  pips_assert("ref offset undefined", offset != (intptr_t) HASH_UNDEFINED_VALUE);
484  }
485  else
486  {
487  offset = 1;
488  }
489 
490  string effAction = hash_get(gRefToEff, curRef);
491 
492  pips_assert("effAction != HASH_UNDEFINED_VALUE",
493  effAction != HASH_UNDEFINED_VALUE);
494 
495  //printf("mmcd ref\n");
496  //print_reference(curRef);printf("\n");
497 
498  if(!strcmp(effAction, R_EFFECT))
499  {
500  //printf("read eff\n");
501 
502  statement readStat = generate_mmcd_stat_from_ref(curRef, offset,
503  count, true,
504  lToggleEnt);
505 
506  //print_statement(readStat);
507 
508  *lReadStats = gen_nconc(*lReadStats, CONS(STATEMENT, readStat, NIL));
509 
510  lReadDone = gen_nconc(lReadDone, CONS(REFERENCE, curRef, NIL));
511  }
512  else
513  {
514  //printf("write eff\n");
515 
516  statement writeStat = generate_mmcd_stat_from_ref(curRef, offset,
517  count, false,
518  lToggleEnt);
519 
520  //print_statement(writeStat);
521 
522  *lWriteStats = gen_nconc(*lWriteStats, CONS(STATEMENT, writeStat, NIL));
523 
524  lWriteDone = gen_nconc(lWriteDone, CONS(REFERENCE, curRef, NIL));
525  }
526 
527  }, lRef);
528 
529  gen_free_list(lReadDone);
530  gen_free_list(lWriteDone);
531 }
532 
533 /*
534 This function creates a statement to increment the value of the step
535 variable
536  */
538 {
541  int_to_expression(incNum),
542  NULL);
543 
545  addArg));
546 
548 }
549 
550 /*
551 This function creates a statement that has to be put at the
552 beginning of a generated loop statement to move forward in the pipeline
553  */
555 {
556  loop curLoop = statement_loop(stat);
557 
558  statement stepStat;
559 
560  if(gGenHRE)
561  {
562  stepStat = make_wait_step_statement();
563  }
564  else
565  {
566  stepStat = make_step_inc_statement(1);
567  }
568 
570  entity_to_expression(newOuterInd),
572  NULL);
573 
574  expression neExp =
576  neArg));
577 
578  test t = make_test(neExp, stepStat, make_empty_statement());
579 
580  stepStat = make_statement(entity_empty_label(),
585  NIL,NULL,
587 
588  return stepStat;
589 }
590 
591 /*
592 This function is used by has_loop_inside
593  */
594 static bool has_loop_inside_flt(statement stat, bool * bHasLoop)
595 {
596  instruction instr = statement_instruction(stat);
597 
598  switch(instruction_tag(instr))
599  {
600  case is_instruction_loop:
603  {
604  *bHasLoop = true;
605  return false;
606  break;
607  }
608 
610  case is_instruction_test:
611  {
612  return true;
613  break;
614  }
615  case is_instruction_call:
616  {
617  break;
618  }
619  default:
620  {
621  pips_internal_error("unsupported tag");
622  break;
623  }
624  }
625 
626  return false;
627 }
628 
629 /*
630 This function returns true if statement stat contains a call statement.
631  */
632 static bool has_loop_inside(statement stat)
633 {
634  bool bHasLoop = false;
635 
636  gen_context_recurse(stat, &bHasLoop,
638 
639  return bHasLoop;
640 }
641 
642 /*
643 This function creates a fifo associated to entity ent.
644  */
645 static int alloc_new_slot(entity ent)
646 {
647  static intptr_t curFifo = -1;
648  static intptr_t curInd = 0;
649 
650  /*if((curFifo == -1) || (curInd == get_int_property("COMENGINE_SIZE_OF_FIFO")))
651  {*/
652  curFifo = get_realFifoNum(-1);
653 
654  curInd = 0;
655  //}
656 
657  hash_put(gEntToHREFifo, ent, (void*)curFifo);
658 
659  hash_put(gIndToNum, ent, (void*)curInd++);
660 
661  return curFifo;
662 }
663 
664 /*
665 This function creates a MMCD statement to update the toggle value in the
666 HRE fifo.
667  */
669 {
670  int fifoNum = alloc_new_slot(ent);
671 
672  statement newStat =
674  int_to_expression(fifoNum),
677  int_to_expression(1));
678 
679  return newStat;
680 }
681 
682 /*
683 This function finds or creates a fifo associated to entity ent.
684  */
686 {
687  intptr_t fifoNum = (intptr_t)hash_get(gEntToHREFifo, ent);
688 
689  if(fifoNum == (intptr_t)HASH_UNDEFINED_VALUE)
690  {
691  fifoNum = alloc_new_slot(ent);
692  }
693 
694  return fifoNum;
695 }
696 
697 /*
698 This function creates a MMCD statement to update the newInd value in the
699 HRE fifo.
700  */
702 {
703  //printf("make_init_newInd_stat beg\n");
704 
705  list lUnSupportedRef = hash_get(gLoopToUnSupRef, stat);
706 
707  pips_assert("lUnSupportedRef != HASH_UNDEFINED_VALUE",
708  lUnSupportedRef != HASH_UNDEFINED_VALUE);
709 
710  if((!has_loop_inside(loop_body(statement_loop(stat)))) &&
711  (lUnSupportedRef == NIL))
712  {
713  return statement_undefined;
714  }
715 
716  int fifoNum = find_or_create_slot(loop_index(statement_loop(stat)));
717 
718  statement newStat =
720  int_to_expression(fifoNum),
721  entity_to_expression(newInd),
723  int_to_expression(1));
724 
725  //printf("make_init_newInd_stat end\n");
726  return newStat;
727 }
728 
729 /*
730 This functions creates statements that are put at the beginning ot the body
731 of the loop tiling outer loop
732  */
734  entity transferSize, expression bufferSizeExp)
735 {
736  statement newStat = statement_undefined;
737 
738  loop curLoop = statement_loop(stat);
739 
740  list rgSizeArg1 = gen_make_list(expression_domain,
742  copy_expression(bufferSizeExp),
743  NULL);
744 
745  expression rgSizeExp1 =
747  rgSizeArg1));
748 
749 
751  copy_expression(bufferSizeExp),
752  rgSizeExp1,
753  NULL);
754 
756  arg2Arg));
757 
759  arg2,
760  entity_to_expression(newOuterInd),
761  NULL);
762 
763  expression leExp =
765  leArg));
766 
769  copy_expression(bufferSizeExp),
770  NULL);
771 
772  expression modExp =
774  modArg));
775 
777  modExp,
779  NULL);
780 
781  expression addExp =
783  addArg));
784 
785  statement trueStat = make_assign_statement(entity_to_expression(transferSize),
786  addExp);
787 
788  statement falseStat = make_assign_statement(entity_to_expression(transferSize),
789  copy_expression(bufferSizeExp));
790 
791  expression rgUpper = range_upper(loop_range(curLoop));
792  intptr_t upVal = -1;
793  intptr_t rate = -1;
794  expression_integer_value(rgUpper, &upVal);
795  expression_integer_value(bufferSizeExp, &rate);
796 
797  if((upVal != -1) &&
798  (rate != -1) &&
799  ((upVal+1)%rate == 0))
800  {
801  free_expression(leExp);
802  free_statement(trueStat);
803  newStat = falseStat;
804  }
805  else if((upVal+1) < rate)
806  {
807  free_expression(leExp);
808  free_statement(falseStat);
809  newStat = trueStat;
810  }
811  else
812  {
813  test t = make_test(leExp, trueStat, falseStat);
814 
815  newStat = make_statement(entity_empty_label(),
820  NIL,NULL,
822  }
823 
824  /*statement stepStat = make_loop_step_stat(stat, newOuterInd);
825 
826  newStat = make_block_statement(gen_nconc(CONS(STATEMENT, stepStat, NIL),
827  CONS(STATEMENT, newStat, NIL)));
828  */
829  /*if(!gGenHRE)
830  {
831  statement indStat = make_init_newInd_stat(stat, newOuterInd);
832 
833  if(indStat != statement_undefined)
834  {
835  newStat =
836  make_block_statement(gen_nconc(CONS(STATEMENT, newStat, NIL),
837  CONS(STATEMENT, indStat, NIL)));
838  }
839  }
840 */
841  return newStat;
842 }
843 
845 
846 /*
847 This function is used by comEngine_replace_reference_in_stat
848  */
850 {
854  {
856 
858 
860 
862 
864  }
865 }
866 
867 /*
868 This function replace all the references equal to ref in statement stat
869 by the expression new.
870  */
872  reference ref, expression new)
873 {
874  gRefToReplace = ref;
875 
876  gen_context_recurse(stat, new,
878 }
879 
880 /*
881 This function creates the MMCD Load and Store statements generated from
882 lSupportedRef
883  */
884 static list make_mmcd_stats_from_ref(statement stat, list lSupportedRef, hash_table htOffset,
885  entity transferSize, entity newOuterInd, statement innerStat)
886 {
887  loop curLoop = statement_loop(stat);
888 
889  list lStats = NIL;
890 
891  list lSupReadStats = NIL;
892  list lSupWriteStats = NIL;
893 
894  list lToggleEnt = hash_get(gLoopToToggleEnt, stat);
895 
896  pips_assert("lToggleEnt != HASH_UNDEFINED_VALUE",
897  lToggleEnt != HASH_UNDEFINED_VALUE);
898 
899  generate_mmcd_stats_from_ref(lSupportedRef, htOffset,
900  entity_to_expression(transferSize), lToggleEnt,
901  &lSupReadStats, &lSupWriteStats);
902 
903  MAP(REFERENCE, curRef,
904  {
905  hash_put(gRefToInd, curRef, loop_index(statement_loop(stat)));
906  }, lSupportedRef);
907 
908  MAP(REFERENCE, curRef,
909  {
910  entity toggleEnt = get_toggleEnt_from_ref(curRef, lToggleEnt);
911 
912  hash_put(gRefToToggle, curRef, toggleEnt);
913 
914  }, lSupportedRef);
915 
916  MAP(STATEMENT, curStat,
917  {
919  make_reference(loop_index(curLoop), NIL),
920  entity_to_expression(newOuterInd));
921  }, lSupReadStats);
922 
923  MAP(STATEMENT, curStat,
924  {
926  make_reference(loop_index(curLoop), NIL),
927  entity_to_expression(newOuterInd));
928  }, lSupWriteStats);
929 
930  lStats = gen_nconc(lStats, lSupReadStats);
931 
932  if(innerStat != statement_undefined)
933  {
934  lStats = gen_nconc(lStats, CONS(STATEMENT, innerStat, NIL));
935  }
936 
937  lStats = gen_nconc(lStats, lSupWriteStats);
938 
939  return lStats;
940 }
941 
942 static list make_lStats(statement stat, entity transferSize,
943  statement innerStat, entity newOuterInd,
944  list lSupportedRef, hash_table htOffset,
945  expression bufferSizeExp)
946 {
947  list lStats = NIL;
948 
949  statement transStat = make_transStat(stat, newOuterInd,
950  transferSize, bufferSizeExp);
951 
952  lStats = gen_nconc(lStats, CONS(STATEMENT, transStat, NIL));
953 
954  list lTemp = NIL;
955 
956  lTemp = make_mmcd_stats_from_ref(stat, lSupportedRef, htOffset,
957  transferSize, newOuterInd, innerStat);
958 
959  lStats = gen_nconc(lStats, lTemp);
960 
961  return lStats;
962 }
963 
964 /*
965 This function creates an Execution MMCD
966  */
968 {
969  static int number = 0;
970 
973  int_to_expression(number++),
974  NULL);
975 
976  statement mmcdStat =
979  arg));
980 
981  return mmcdStat;
982 }
983 
984 /*
985 This function generates the Load and Store MMCD statements associated
986 to lRef. Then, it updates the step value and concatenate the created
987 statements to stat
988  */
990  statement stat)
991 {
992  list lStats = NIL;
993 
994  list lReadStats = NIL;
995  list lWriteStats = NIL;
996 
997  generate_mmcd_stats_from_ref(lRef, NULL,
999  lToggleEnt,
1000  &lReadStats, &lWriteStats);
1001 
1002  statement stepStat1 = make_step_inc_statement(1);
1003  statement stepStat2 = make_step_inc_statement(2);
1004 
1005  lStats = gen_nconc(CONS(STATEMENT, stepStat1, NIL), lReadStats);
1006  if(stat != statement_undefined)
1007  {
1008  lStats = gen_nconc(lStats, CONS(STATEMENT, stat, NIL));
1009  }
1010  lStats = gen_nconc(lStats, lWriteStats);
1011 
1012  if(lWriteStats != NIL)
1013  {
1014  lStats = gen_nconc(lStats, CONS(STATEMENT, stepStat2, NIL));
1015  }
1016 
1017  return make_block_statement(lStats);
1018 }
1019 
1020 /*
1021 This function generates the Load and Store MMCD statements associated
1022 to lRef. Then, it updates the step value and concatenate the created
1023 statements to stat
1024  */
1026 {
1027  list lStats = NIL;
1028 
1029  list lReadStats = NIL;
1030  list lWriteStats = NIL;
1031 
1032  generate_mmcd_stats_from_ref(lRef, NULL,
1033  int_to_expression(1),
1034  NIL,
1035  &lReadStats, &lWriteStats);
1036 
1037  statement stepStat1 = make_step_inc_statement(1);
1038  statement stepStat2 = make_step_inc_statement(2);
1039 
1040  lStats = gen_nconc(CONS(STATEMENT, stepStat1, NIL), lReadStats);
1041 
1042  lStats = gen_nconc(lStats, lInStats);
1043 
1044  lStats = gen_nconc(lStats, lWriteStats);
1045 
1046  if(lWriteStats != NIL)
1047  {
1048  lStats = gen_nconc(lStats, CONS(STATEMENT, stepStat2, NIL));
1049  }
1050 
1051  return lStats;
1052 }
1053 
1054 /*
1055 This function replace in stat the old index by the new ones
1056  */
1058  entity newOuterInd, entity newInnerInd)
1059 {
1061  entity_to_expression(newOuterInd),
1062  entity_to_expression(newInnerInd),
1063  NULL);
1064 
1066  addArg));
1067 
1069  make_reference(oldInd, NIL),
1070  arg2);
1071 }
1072 
1073 /*
1074 This function computes the supported and unsupported references and
1075 memorize them in gLoopToSupRef and gLoopToUnSupRef
1076  */
1078  list * lSupportedRef, list * lUnSupportedRef)
1079 {
1080  loop curLoop = statement_loop(stat);
1081 
1082  list lRef = hash_get(gLoopToRef, stat);
1083 
1084  if(lRef == HASH_UNDEFINED_VALUE)
1085  {
1086  lRef = NIL;
1087  }
1088 
1089  MAP(REFERENCE, curRef,
1090  {
1091  //printf("loop ref\n");
1092  //print_reference(curRef);printf("\n");
1093 
1094  if(supported_ref_p(curRef, loop_index(curLoop), htOffset))
1095  {
1096  *lSupportedRef = gen_nconc(*lSupportedRef, CONS(REFERENCE, curRef, NIL));
1097  }
1098  else
1099  {
1100  *lUnSupportedRef = gen_nconc(*lUnSupportedRef, CONS(REFERENCE, curRef, NIL));
1101  }
1102 
1103  }, lRef);
1104 
1105  hash_put(gLoopToSupRef, stat, *lSupportedRef);
1106  hash_put(gLoopToUnSupRef, stat, *lUnSupportedRef);
1107 }
1108 
1110 {
1111  return statement_undefined;
1112 }
1113 
1115  statement innerStat, entity newOuterInd,
1116  list lSupportedRef, hash_table htOffset,
1117  expression bufferSizeExp)
1118 {
1119  return make_lStats(stat, transferSize,
1120  innerStat, newOuterInd,
1121  lSupportedRef, htOffset,
1122  bufferSizeExp);
1123 }
1124 
1125 /*
1126 This function creates a statement that make sure that the out effect of
1127 the old index of curLoop is respected
1128  */
1130 {
1131  statement assignStat =
1134 
1135  return gen_nconc(lStats, CONS(STATEMENT, assignStat, NIL));
1136 }
1137 
1138 /*
1139 This function generates the MMCD code from a test
1140 statement.
1141  */
1143 {
1144  printf("generate_code_test\n");
1145  print_statement(stat);printf("\n");
1146  statement newStat = statement_undefined;
1147 
1148  newStat = get_call_stat_proc(stat);
1149 
1150  list lRef = hash_get(gStatToRef, stat);
1151 
1152  if(lRef != HASH_UNDEFINED_VALUE)
1153  {
1154  newStat = generate_stat_from_ref_list_proc(lRef, NIL, newStat);
1155  }
1156 
1157  // Get the new statements for the true statement
1158  statement trueStat = generate_code_function(test_true(statement_test(stat)), false);
1159 
1160  // Get the new statements for the false statement
1161  statement falseStat = generate_code_function(test_false(statement_test(stat)), false);
1162 
1163  list lStats = NIL;
1164 
1165  if(newStat != statement_undefined)
1166  {
1167  lStats = gen_nconc(lStats, CONS(STATEMENT, newStat, NIL));
1168  }
1169 
1170  if(trueStat != statement_undefined)
1171  {
1172  lStats = gen_nconc(lStats, CONS(STATEMENT, trueStat, NIL));
1173  }
1174 
1175  if(falseStat != statement_undefined)
1176  {
1177  lStats = gen_nconc(lStats, CONS(STATEMENT, falseStat, NIL));
1178  }
1179 
1180  newStat = make_block_statement(lStats);
1181 
1182  return newStat;
1183 }
1184 
1185 /*
1186 This function adds some bubbles in the pipeline if needed
1187  */
1189 {
1190  bool loopSync = (intptr_t)hash_get(gLoopToSync, stat);
1191 
1192  if(loopSync == (intptr_t)HASH_UNDEFINED_VALUE)
1193  {
1194  return lInStats;
1195  }
1196 
1197  statement stepStat = make_step_inc_statement(2);
1198 
1199  list lStats = NIL;
1200 
1201  lStats = gen_nconc(lStats, lInStats);
1202  lStats = gen_nconc(lStats, CONS(STATEMENT, stepStat, NIL));
1203 
1204  return lInStats;
1205 }
1206 
1207 /*
1208 This function creates the real fifos associated to lRef references
1209  */
1211 {
1212  list lDone = NIL;
1213 
1214  pips_assert("true", stat==stat);
1215 
1216  //bool readAndWrite = false;
1217 
1218  MAP(REFERENCE, curRef1,
1219  {
1220  bool bDone = false;
1221 
1222  MAP(REFERENCE, refDone,
1223  {
1224  if(reference_equal_p(curRef1, refDone))
1225  {
1226  hash_put(gRefToFifoOff, hash_get(gRefToFifo, refDone), (void *)3);
1227  bDone = true;
1228  break;
1229  }
1230  }, lDone);
1231 
1232  if(bDone)
1233  continue;
1234 
1235  void* fifoNum = hash_get(gRefToFifo, curRef1);
1236 
1237  pips_assert("fifoNum != HASH_UNDEFINED_VALUE",
1238  fifoNum != HASH_UNDEFINED_VALUE);
1239 
1240  hash_put(gRefToFifoOff, fifoNum, (void *)2);
1241 
1242  MAP(REFERENCE, curRef2,
1243  {
1244  if(reference_equal_p(curRef1, curRef2))
1245  {
1246  string effAction1 = hash_get(gRefToEff, curRef1);
1247 
1248  pips_assert("effAction1 != HASH_UNDEFINED_VALUE",
1249  effAction1 != HASH_UNDEFINED_VALUE);
1250 
1251  string effAction2 = hash_get(gRefToEff, curRef2);
1252 
1253  pips_assert("effAction2 != HASH_UNDEFINED_VALUE",
1254  effAction2 != HASH_UNDEFINED_VALUE);
1255 
1256  if(strcmp(effAction1, effAction2))
1257  {
1258  hash_put(gRefToFifoOff, fifoNum, (void *)3);
1259 
1260  lDone = CONS(REFERENCE, curRef1, lDone);
1261 
1262  break;
1263  }
1264  }
1265  }, lRef);
1266  }, lRef);
1267 
1268  gen_free_list(lDone);
1269 
1270  printf("create_realFifo_proc\n");
1271  MAP(REFERENCE, curRef,
1272  {
1273  printf("create_realFifo_proc it\n");
1274  print_reference(curRef);printf("\n");
1275  intptr_t fifoNum = (intptr_t)hash_get(gRefToFifo, curRef);
1276 
1277  pips_assert("fifoNum != HASH_UNDEFINED_VALUE",
1278  fifoNum != (intptr_t)HASH_UNDEFINED_VALUE);
1279 
1280  get_realFifoNum(fifoNum);
1281  }, lRef);
1282 
1283  printf("create_realFifo_proc end\n");
1284 }
1285 
1286 /*
1287 This function generates the MMCDs generation code
1288  */
1290  statement externalized_code,
1291  _UNUSED_ list l_in,
1292  _UNUSED_ list l_out)
1293 {
1294  statement newStat;
1295 
1296  // Initialize some global variables
1301  (strdup("step"),
1302  make_basic(is_basic_int, (void*)4));
1303  gGenHRE = false;
1304 
1305  // Do the job
1306  newStat = comEngine_generate_code(externalized_code);
1307 
1308  // Add the step variable initialization
1309  statement stepStat =
1311  int_to_expression(1));
1312 
1313  // Add the start HRE statement
1314  statement startStat =
1316  NIL));
1317 
1318  // Add the wait HRE statement
1319  statement waitStat =
1321  NIL));
1322 
1324  stepStat,
1325  newStat,
1326  startStat,
1327  waitStat,
1328  NULL);
1329 
1330  newStat = make_block_statement(lStats);
1331 
1332  // Fre some global variables
1335 
1336  //printf("final newStat\n");
1337  //print_statement(newStat);
1338 
1339  return newStat;
1340 }
void free_normalized(normalized p)
Definition: ri.c:1407
call make_call(entity a1, list a2)
Definition: ri.c:269
basic make_basic(enum basic_utype tag, void *val)
Definition: ri.c:155
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
test make_test(expression a1, statement a2, statement a3)
Definition: ri.c:2607
statement make_statement(entity a1, intptr_t a2, intptr_t a3, string a4, instruction a5, list a6, string a7, extensions a8, synchronization a9)
Definition: ri.c:2222
void free_expression(expression p)
Definition: ri.c:853
instruction make_instruction(enum instruction_utype tag, void *val)
Definition: ri.c:1166
reference copy_reference(reference p)
REFERENCE.
Definition: ri.c:2047
void free_syntax(syntax p)
Definition: ri.c:2445
synchronization make_synchronization_none(void)
Definition: ri.c:2424
void free_statement(statement p)
Definition: ri.c:2189
static int count
Definition: SDG.c:519
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
void const char const char const int
#define R_EFFECT
Definition: comEngine.h:29
#define GEN_LOAD_MMCD
Definition: comEngine.h:40
#define WAIT_FOR_HRE
Definition: comEngine.h:43
#define GEN_STORE_MMCD
Definition: comEngine.h:41
#define START_HRE
Definition: comEngine.h:42
hash_table gLoopToToggleEnt
hash_table gLoopToSupRef
hash_table gStatToRef
hash_table gRefToFifoOff
hash_table gLoopToRef
comEngine_distribute.c
hash_table gRefToFifo
hash_table gLoopToSync
hash_table gRefToInd
hash_table gToggleToInc
hash_table gRefToHREFifo
hash_table gRefToToggle
hash_table gIndToNum
hash_table gEntToHREFifo
hash_table gRefToEff
hash_table gLoopToUnSupRef
statement make_wait_step_statement()
entity comEngine_make_new_scalar_variable(const char *prefix, basic bas)
statement comEngine_generate_code(statement stat)
statement generate_code_function(statement stat, bool bCalledFromSeq)
bool gGenHRE
void comEngine_replace_reference_in_stat(statement stat, reference ref, expression new)
list generate_stat_from_ref_list_proc_list(list lRef, list lInStats)
static bool has_call_stat_inside_flt(statement stat, bool *bHasCallStat)
statement make_toggle_mmcd(entity ent)
list process_gLoopToSync_proc(statement stat, list lInStats)
static bool has_loop_inside_flt(statement stat, bool *bHasLoop)
static void has_call_stat_inside_rwt(_UNUSED_ statement stat, _UNUSED_ bool *bHasCallStat)
static hash_table gOldRefToHREFifo
statement get_call_stat_proc(_UNUSED_ statement stat)
statement comEngine_generate_procCode(statement externalized_code, _UNUSED_ list l_in, _UNUSED_ list l_out)
statement make_init_newInd_stat(statement stat, entity newInd)
static void comEngine_replace_reference_in_stat_rwt(expression exp, expression newExp)
static void generate_mmcd_stats_from_ref(list lRef, hash_table htOffset, expression count, list lToggleEnt, list *lReadStats, list *lWriteStats)
static bool get_final_offset(list lRefDim, intptr_t offset, int rank, intptr_t *retVal)
static hash_table gRealFifo
static int alloc_new_slot(entity ent)
static intptr_t get_realFifoNum(intptr_t fifoNum)
static int find_or_create_slot(entity ent)
list add_index_out_effect_proc(loop curLoop, list lStats)
void get_supportedRef_proc(statement stat, hash_table htOffset, list *lSupportedRef, list *lUnSupportedRef)
static bool supported_ref_p(reference ref, entity index, hash_table htOffset)
statement generate_stat_from_ref_list_proc(list lRef, list lToggleEnt, statement stat)
statement make_transStat(statement stat, entity newOuterInd, entity transferSize, expression bufferSizeExp)
static statement generate_mmcd_stat_from_ref(reference curRef, int offset, expression count, bool bRead, list lToggleEnt)
static statement make_mmcd_load_store_stat(string name, expression hreBuff, expression refExp, expression offExp, expression countExp)
statement make_step_inc_statement(int incNum)
static bool has_loop_inside(statement stat)
static entity gStepEnt
static list make_lStats(statement stat, entity transferSize, statement innerStat, entity newOuterInd, list lSupportedRef, hash_table htOffset, expression bufferSizeExp)
static entity get_toggleEnt_from_ref(reference curRef, list lToggleEnt)
statement make_loop_step_stat(statement stat, entity newOuterInd)
static reference gRefToReplace
static list make_mmcd_stats_from_ref(statement stat, list lSupportedRef, hash_table htOffset, entity transferSize, entity newOuterInd, statement innerStat)
list make_loop_lStats_proc(statement stat, entity transferSize, statement innerStat, entity newOuterInd, list lSupportedRef, hash_table htOffset, expression bufferSizeExp)
void create_realFifo_proc(statement stat, list lRef)
bool has_call_stat_inside(statement stat)
comEngine_generate_procCode.c
void process_innerStat1_proc(statement stat, entity oldInd, entity newOuterInd, entity newInnerInd)
statement make_exec_mmcd()
statement generate_code_test_proc(statement stat)
static Value offset
Definition: translation.c:283
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
Definition: genC.h:285
bool success
Definition: gpips-local.h:59
statement make_block_statement(list)
Make a block statement from a list of statement.
Definition: statement.c:616
void gen_null2(__attribute__((unused)) void *u1, __attribute__((unused)) void *u2)
idem with 2 args, to please overpeaky compiler checks
Definition: genClib.c:2758
bool gen_true2(__attribute__((unused)) gen_chunk *u1, __attribute__((unused)) void *u2)
Definition: genClib.c:2785
list gen_make_list(int domain,...)
Definition: list.c:851
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
size_t gen_length(const list l)
Definition: list.c:150
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
gen_chunk gen_nth(int n, const list l)
to be used as ENTITY(gen_nth(3, l))...
Definition: list.c:710
#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
loop statement_loop(statement)
Get the loop of a statement.
Definition: statement.c:1374
test statement_test(statement)
Get the test of a statement.
Definition: statement.c:1348
statement make_assign_statement(expression, expression)
Definition: statement.c:583
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:449
void hash_put(hash_table htp, const void *key, const void *val)
This functions stores a couple (key,val) in the hash table pointed to by htp.
Definition: hash.c:364
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
#define _UNUSED_
Definition: misc-local.h:232
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_internal_error
Definition: misc-local.h:149
static entity rank
#define STATEMENT_ORDERING_UNDEFINED
mapping.h inclusion
Definition: newgen-local.h:35
#define HASH_MAP(k, v, code, ht)
Definition: newgen_hash.h:60
@ hash_pointer
Definition: newgen_hash.h:32
#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
void print_reference(reference r)
Definition: expression.c:142
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
static void norm(struct rproblem *RR)
cette procedure normalise la fonction cout, calcule les valeurs des seconds membres resultant d'une n...
Definition: r1.c:271
#define C_LESS_OR_EQUAL_OPERATOR_NAME
#define C_GREATER_THAN_OPERATOR_NAME
#define C_MODULO_OPERATOR_NAME
#define PLUS_OPERATOR_NAME
#define NORMALIZE_EXPRESSION(e)
#define STATEMENT_NUMBER_UNDEFINED
default values
#define call_to_statement(c)
#define DIVIDE_OPERATOR_NAME
#define empty_comments
Empty comments (i.e.
#define MULTIPLY_OPERATOR_NAME
#define PLUS_C_OPERATOR_NAME
#define make_empty_statement
An alias for make_empty_block_statement.
entity entity_empty_label(void)
Definition: entity.c:1105
entity module_name_to_runtime_entity(const char *name)
similar to module_name_to_entity but generates a warning and a stub if the entity is not found
Definition: entity.c:1485
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
bool expression_integer_value(expression e, intptr_t *pval)
Definition: eval.c:792
expression reference_to_expression(reference r)
Definition: expression.c:196
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
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 reference_equal_p(reference r1, reference r2)
Definition: expression.c:1500
bool integer_constant_expression_p(expression e)
positive integer constant expression: call to a positive constant or to a sum of positive integer con...
Definition: expression.c:903
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
int integer_constant_expression_value(expression e)
Definition: expression.c:1545
expression call_to_expression(call c)
Build an expression that call a function or procedure.
Definition: expression.c:309
extensions empty_extensions(void)
extension.c
Definition: extension.c:43
#define loop_body(x)
Definition: ri.h:1644
@ is_basic_int
Definition: ri.h:571
#define normalized_undefined
Definition: ri.h:1745
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154
#define REFERENCE(x)
REFERENCE.
Definition: ri.h:2296
#define normalized_linear_p(x)
Definition: ri.h:1779
#define reference_variable(x)
Definition: ri.h:2326
#define range_upper(x)
Definition: ri.h:2290
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define test_false(x)
Definition: ri.h:2837
#define dimension_lower(x)
Definition: ri.h:980
#define type_variable(x)
Definition: ri.h:2949
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define entity_undefined
Definition: ri.h:2761
#define expression_undefined
Definition: ri.h:1223
@ is_instruction_whileloop
Definition: ri.h:1472
@ is_instruction_test
Definition: ri.h:1470
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_sequence
Definition: ri.h:1469
@ is_instruction_forloop
Definition: ri.h:1477
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define expression_normalized(x)
Definition: ri.h:1249
#define test_true(x)
Definition: ri.h:2835
#define dimension_upper(x)
Definition: ri.h:982
#define reference_indices(x)
Definition: ri.h:2328
#define range_lower(x)
Definition: ri.h:2288
#define variable_dimensions(x)
Definition: ri.h:3122
#define statement_instruction(x)
Definition: ri.h:2458
#define loop_range(x)
Definition: ri.h:1642
#define entity_type(x)
Definition: ri.h:2792
#define normalized_linear(x)
Definition: ri.h:1781
#define expression_syntax(x)
Definition: ri.h:1247
#define type_variable_p(x)
Definition: ri.h:2947
#define loop_index(x)
Definition: ri.h:1640
#define statement_undefined
Definition: ri.h:2419
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
char * strdup()
int printf()
#define intptr_t
Definition: stdint.in.h:294
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207
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
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