PIPS
ikernels.c
Go to the documentation of this file.
1 /*
2  Copyright 1989-2016 MINES ParisTech
3  Copyright 2010 HPC Project
4 
5  This file is part of PIPS.
6 
7  PIPS is free software: you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by
9  the Free Software Foundation, either version 3 of the License, or
10  any later version.
11 
12  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
13  WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  FITNESS FOR A PARTICULAR PURPOSE.
15 
16  See the GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
20 
21  */
22 
23 /**
24  * @file ikernels.c
25  * kernels manipulation
26  * @author Mehdi Amini <mehdi.amini@hpc-project.com>
27  */
28 
29 #ifdef HAVE_CONFIG_H
30 #include "pips_config.h"
31 #endif
32 #include <ctype.h>
33 
34 #include "genC.h"
35 #include "linear.h"
36 #include "ri.h"
37 #include "kernel_memory_mapping.h"
38 #include "effects.h"
39 #include "ri-util.h"
40 #include "prettyprint.h" // for debugging
41 #include "workspace-util.h"
42 #include "semantics.h"
43 #include "effects-util.h"
44 #include "text.h"
45 #include "pipsdbm.h"
46 #include "resources.h"
47 #include "properties.h"
48 #include "misc.h"
49 #include "control.h"
50 #include "callgraph.h"
51 #include "effects-generic.h"
52 #include "effects-simple.h"
53 #include "effects-convex.h"
54 #include "text-util.h"
55 #include "parser_private.h"
56 #include "preprocessor.h"
57 #include "transformer.h"
58 #include "accel-util.h"
59 
60 /** Make a sizeof expression
61  *
62  */
64  type array_type = entity_type(e);
65  pips_assert("Must be a variable type", type_variable_p(array_type));
66  variable v_type = type_variable(array_type);
67 
68 
69  // FIXME free memory
70  type element_type = make_type_variable(
72  copy_basic(variable_basic(v_type)),
73  NIL,NIL)
74  );
75 
76  expression transfer_size = SizeOfDimensions(variable_dimensions(v_type));
77  transfer_size=MakeBinaryCall(
82  ),
83  transfer_size);
84 
85  return transfer_size;
86 }
87 
88 /**
89  * converts a region_to_dma_switch to corresponding dma name
90  * according to properties
91  */
92 static const char* get_dma_name(enum region_to_dma_switch m, int d) {
93  char *seeds[] = { "KERNEL_LOAD_STORE_LOAD_FUNCTION",
94  "KERNEL_LOAD_STORE_STORE_FUNCTION",
95  "KERNEL_LOAD_STORE_ALLOCATE_FUNCTION",
96  "KERNEL_LOAD_STORE_DEALLOCATE_FUNCTION" };
97  const char * propname = seeds[(int)m];
98  /* If the DMA is not scalar, the DMA function name is in the property
99  of the form KERNEL_LOAD_STORE_LOAD/STORE_FUNCTION_dD: */
100  char * apropname=NULL;
101  if(d > 0 && (int)m < 2)
102  asprintf(&apropname, "%s_%dD", seeds[(int)m], (int)d);
103  const char* dmaname = get_string_property(propname);
104  if(apropname)
105  free(apropname);
106  pips_debug(6,"Get dma name : %s\n",dmaname);
107  return dmaname;
108 }
109 
111 
112  const char* function_name = get_dma_name(dma, 0);
113  entity mcpy = module_name_to_entity(function_name);
114  if(entity_undefined_p(mcpy)) {
115  mcpy
116  = make_empty_subroutine(function_name,
118  pips_user_warning("Cannot find \"%s\" method. Are you sure you have set\n"
119  "KERNEL_LOAD_STORE_..._FUNCTION "
120  "to a defined entity and added the correct .c file?\n",function_name);
121  } else {
123  }
124  list args = NIL;
125  /*
126  expression entity_exp = entity_to_expression(e);
127  if(entity_pointer_p(e)) {
128  entity_exp = MakeUnaryCall(entity_intrinsic(DEREFERENCING_OPERATOR_NAME),
129  entity_to_expression(e));
130  }
131 
132  expression size_of_e = MakeSizeofExpression(entity_exp);*/
134 
135  args = make_expression_list(entity_to_expression(e),size_of_e);
136 
137  call c = make_call(mcpy, args);
139 }
140 
141 #define INIT_STATEMENT_SIZE 20
142 #define INIT_ENTITY_SIZE 10
143 
144 /* Macro to create set */
145 #define MAKE_SET() (set_make( set_pointer ))
146 
147 /* copy_from_in maps each statement to the "copy from" data that are in-coming
148  * the statement
149  * */
151 #define COPY_FROM_IN(st) ((set)hash_get(copies_from_in, (char *)st))
152 /*
153 set COPY_FROM_IN(statement st) {
154  set res = (set)hash_get(copies_from_in, (char *)st);
155  if(res == HASH_UNDEFINED_VALUE) {
156  res = MAKE_SET();
157  hash_put(copies_from_in, (char *)res, (char *)MAKE_SET());
158  }
159  return res;
160 }
161 */
162 /* copy_from_out maps each statement to the "copy from" data that are out-going
163  * from the statement
164  * */
166 #define COPY_FROM_OUT(st) ((set)hash_get(copies_from_out, (char *)st))
167 /*
168 set COPY_FROM_OUT(statement st) {
169  set res = (set)hash_get(copies_from_out, (char *)st);
170  if(res == HASH_UNDEFINED_VALUE) {
171  res = MAKE_SET();
172  hash_put(copies_from_out, (char *)res, (char *)MAKE_SET());
173  }
174  return res;
175 }
176 */
177 
178 /* copy_to_in maps each statement to the "copy to" data that are in-coming the
179  * statement */
181 #define COPY_TO_IN(st) ((set)hash_get(copies_to_in, (char *)st))
182 /*
183 set COPY_TO_IN(statement st) {
184  set res = (set)hash_get(copies_to_in, (char *)st);
185  if(res == HASH_UNDEFINED_VALUE) {
186  res = MAKE_SET();
187  hash_put(copies_to_in, (char *)res, (char *)MAKE_SET());
188  }
189  return res;
190 }
191 */
192 
193 /* copy_to_out maps each statement to the "copy to" data that are out-going from
194  * the statement */
196 #define COPY_TO_OUT(st) ((set)hash_get(copies_to_out, (char *)st))
197 /*
198 set COPY_TO_OUT(statement st) {
199  set res = (set)hash_get(copies_to_out, (char *)st);
200  if(res == HASH_UNDEFINED_VALUE) {
201  res = MAKE_SET();
202  hash_put(copies_to_out, (char *)res, (char *)MAKE_SET());
203  }
204  return res;
205 
206 }
207 */
208 
210  SET_FOREACH(entity, e, s) {
211  fprintf(stderr,"%s,",entity_name(e));
212  }
213  fprintf(stderr,"\n");
214 }
215 
216 /**
217  * Should be useful, but for some bullshit reason the array dimensions even
218  * for simple case like a[512][512] might be previously normalized "COMPLEX"
219  * This occurs in some special cases...
220  */
223  // Remove a warning
226  }
228  return true;
229 }
230 
232  (void) force_renormalize(e);
233 }
234 
235 /**
236  * Check that an array is fully written by an exact W region in a list
237  */
239  // Ugly hack :-(
241 
242  // Force re-normalization of expression, this is a hack !
244  if(type_variable_p(entity_type(e_used))) {
245  // I don't understand why the gen_recurse doesn't work, so here is the hack for the hack...
249  }
250  }
251 
252  //
257 
258  ifdebug(6) {
259  pips_debug(6,"Array region is : ");
261  }
262  FOREACH(effect, reg, lreg) {
263  if(!descriptor_convex_p(effect_descriptor(reg))) continue;
264  // Proj region over PHI to remove precondition variables
265  // FIXME : Can be done by difference between the 2 bases
266  list proj = base_to_list(sc_base(descriptor_convex(effect_descriptor(reg))));
267  list l_phi = NIL;
269  pips_assert("expression_reference_p", expression_reference_p(e));
272  }
273 
274 
276 
277 
278  ifdebug(6) {
279  pips_debug(6,"Evaluating region : ");
280  print_region(reg);
281  }
282  if(effect_write_p(reg) && store_effect_p(reg) && region_exact_p(reg)) {
283  list ldiff = region_sup_difference(array,reg);
284  bool empty=true;
285  FOREACH(effect, diff, ldiff) {
286  if( !region_empty_p(diff)) {
287  ifdebug(6) {
288  pips_debug(6,"Diff is not empty :");
289  print_region(diff);
290  }
291  empty = false;
292  break;
293  } else {
294  ifdebug(6) {
295  pips_debug(6,"Diff is empty !\n");
296  }
297  }
298  }
299  if(empty) {
300  return true;
301  }
302  }
303  }
304  return false;
305 }
306 
307 /**
308  * Translate the interprocedural summary for a function into a set of local
309  * corresponding parameters (entity only)
310  */
311 static set interprocedural_mapping(string res, call c) {
313  const char* func_name = entity_local_name(callee);
315  func_name,
316  true);
317  set summary = MAKE_SET();
318  set_assign(summary,memory_mapping_map(mem_map));
319 
320 
321  list /* of entity */l_formals = module_formal_parameters(callee);
322  int arg_num, n_formals = gen_length(l_formals);
323  gen_free_list(l_formals);
324 
325  /* if there are more actuals than formals, they are skipped.
326  */
327  set at_call_site = MAKE_SET();
328  list real_args = call_arguments(c);
329  for (arg_num = 1; !ENDP(real_args) && arg_num <= n_formals; real_args
330  = CDR(real_args), arg_num++) {
331  entity formal_ent = find_ith_formal_parameter(callee, arg_num);
332  bool found = false;
333  SET_FOREACH(entity, e, summary) {
334  if(same_entity_p(e, formal_ent)) {
335  set_del_element(summary,summary,e);
336  found = true;
337  break;
338  }
339  }
340  if(found) {
341  expression real_exp = EXPRESSION(CAR(real_args));
342 
343  if(expression_reference_p(real_exp)) {
345  set_add_element(at_call_site, at_call_site, reference_variable(r));
346  } else {
348  "Interprocedural mapping on %s map on a non ref expression ",
349  entity_name(formal_ent));
350  print_syntax(expression_syntax(real_exp));
351  fprintf(stderr, "\n");
352  }
353  }
354  }
355  SET_FOREACH(entity, e, summary) {
356  pips_debug(4,"%s not mapped on formal\n",entity_name(e));
357  if(top_level_entity_p(e)) {
358  set_add_element(at_call_site,at_call_site,e);
359  } else {
360  pips_internal_error("Interprocedural error : entity %s is not a formal"
361  " not a global variable !\n",entity_name(e));
362  }
363  }
364  return at_call_site;
365 }
366 
367 
368 
369 bool is_a_kernel(const char* func_name) {
370  callees kernels = (callees)db_get_memory_resource(DBR_KERNELS, "", true);
371  bool found = false;
372  FOREACH(STRING,kernel_name,callees_callees(kernels)) {
373  if((found = (same_string_p(kernel_name,func_name))))
374  break;
375  }
376  return found;
377 }
378 
379 static void init_one_statement(statement st) {
380  if(COPY_FROM_IN( st ) == (set)HASH_UNDEFINED_VALUE) {
381  /* First initialization (normal use) */
382  /* If the statement has never been seen, allocate new sets: */
383  hash_put(copies_from_in, (char *)st, (char *)MAKE_SET());
384  hash_put(copies_from_out, (char *)st, (char *)MAKE_SET());
385  hash_put(copies_to_in, (char *)st, (char *)MAKE_SET());
386  hash_put(copies_to_out, (char *)st, (char *)MAKE_SET());
387  }
388 }
389 
390 static void copy_from_statement(statement st);
391 
392 static void copy_from_block(statement st, cons *sts) {
393  /* The initial in for the block */
394  set copy_from_in = COPY_FROM_IN( st );
395  /* loop over statements inside the block */
396  FOREACH( statement, one, sts ) {
397  /* propagate "in" sets */
398  set_assign(COPY_FROM_IN( one ), copy_from_in);
399 
400  /* Compute the "copy from" for this statement */
401  copy_from_statement(one);
402 
403  /* Get the ins for next statement */
404  copy_from_in = COPY_FROM_OUT( one );
405  }
406 
407  /* The outs for the whole block */
408  set_assign(COPY_FROM_OUT( st ), copy_from_in);
409 
410 }
411 static void copy_from_test(statement st, test t) {
412  /* Compute true branch */
415 
416  /* Compute false branch */
419 
420 
421  /* Compute "out" sets for the test */
422  set copy_from_out = COPY_FROM_OUT( st );
423 
425 
426 
427  ifdebug(6) {
428  pips_debug(6,"Handling copy from for test expression : ");
430  fprintf(stderr,"\n");
431  pips_debug(6,"Copy from is : ");
432  print_entities(set_to_list(copy_from_out));
433  fprintf(stderr,"\n");
434  }
435 
436  // We remove from "copy from" what is used by this statement
439  if(entity_array_p(e_used)) {
440  pips_debug(6,"Removing %s from copy_out\n",entity_name(e_used));
441  set_del_element(copy_from_out, copy_from_out, e_used);
442  }
443  }
444 
445 
446 }
447 
449  /* Compute "in" sets for the loop body */
450  set_assign(COPY_FROM_IN( body ), COPY_FROM_IN( st ));
451 
452  /* Compute loop body */
453  copy_from_statement(body);
454 
455  /* Fix point */
456  /*
457  if(!set_equal_p(COPY_FROM_IN( body ),set_intersection(COPY_FROM_IN( st ),
458  COPY_FROM_OUT( body ),
459  COPY_FROM_IN( st )))) {
460  return copy_from_all_kind_of_loop(st,body);
461  }
462  */
463 
464  /* Compute "out" sets for the loop */
465  if(true) { //loop_executed_once_p(st, l)) { FIXME !!!!
466  pips_debug(1,"Loop executed once !\n");
467  /* Body is always done at least one time */
468  set_assign(COPY_FROM_OUT( st ), COPY_FROM_OUT( body ));
469  } else {
470  pips_debug(1,"Loop not executed once :-( !\n");
471  /* Body is not always done */
473  COPY_FROM_OUT( body ),
474  COPY_FROM_IN( st ));
475  }
476 
477 }
478 
479 static void copy_from_loop(statement st, loop l) {
480  statement body = loop_body(l);
481  copy_from_all_kind_of_loop(st, body);
482 
483  /*
484  * For further "already_transfered" optimization to be correct !
485  * We have to force to transfert from the accelerator in the body of the loop
486  * if we can't know that the data won't be used on the CPU at the begin of the
487  * next iteration
488  * see validation/Gpu/Comm_optimization.sub/loop01.c
489  */
490  set to_delete = MAKE_SET();
492  if(!set_belong_p(COPY_TO_IN(st),e)) {
493  //insert_statement(body,make_dma_transfert(e,dma_store),false);
494  pips_debug(1,"Removing %s from loop copy-out !\n",entity_name(e));
495  set_add_element(to_delete,to_delete,e);
496  }
497  }
498  set_difference(COPY_FROM_OUT(st),COPY_FROM_OUT(st),to_delete);
499  set_difference(COPY_FROM_OUT(body),COPY_FROM_OUT(body),to_delete);
500  set_free(to_delete);
501 
502 }
504  statement body = whileloop_body(l);
505  copy_from_all_kind_of_loop(st, body);
506 }
507 static void copy_from_forloop(statement st, forloop l) {
508  statement body = forloop_body(l);
509  copy_from_all_kind_of_loop(st, body);
510 }
511 
512 static void copy_from_call(statement st, call c) {
514  const char* func_name = entity_local_name(callee);
515 
516  /* The initial in */
517  set copy_from_in = COPY_FROM_IN( st );
518  set copy_from_out = COPY_FROM_OUT( st );
519 
520  /* The outs is initially the in */
521  set_assign(copy_from_out, copy_from_in);
522  if(is_a_kernel(func_name)) {
523  pips_debug(3,"%s is a Kernel !\n",
524  func_name);
525  // it's a kernel call !!
526  // Let's add the "region out" to copy_from set !
527  list l_out = load_statement_out_regions(st);
528  FOREACH(EFFECT, eff, l_out )
529  {
531  if(entity_array_p(e_used)) {
532  copy_from_out = set_add_element(copy_from_out, copy_from_out, e_used);
533  }
534  }
535  } else {
536  // Standard call (not a kernel)
537  pips_debug(3,"%s is a simple call\n",
538  func_name);
539 
540 
541  // We get the inter-procedural results for copy in
542  set at_call_site;
543  if(user_call_p(c)) { // Ignoring intrinsics
544  at_call_site = interprocedural_mapping(DBR_KERNEL_COPY_IN,c);
545  } else
546  at_call_site = set_make(set_pointer);
547 
548  // We remove from "copy from" what is used by this statement but not what's
549  // in copy-in
552  if(entity_array_p(e_used) && !set_belong_p(at_call_site,e_used)) {
553  pips_debug(6,"Removing %s from copy_out\n",entity_name(e_used));
554  copy_from_out = set_del_element(copy_from_out, copy_from_out, e_used);
555  }
556  }
557 
558  // No longer used
559  set_free(at_call_site);
560 
561  // We add the inter-procedural results for copy out, but not for intrinsics
562  if(user_call_p(c)) { // Ignoring intrinsics
563  at_call_site = interprocedural_mapping(DBR_KERNEL_COPY_OUT,c);
564  copy_from_out = set_union(copy_from_out, at_call_site, copy_from_out);
565  ifdebug(6) {
566  pips_debug(6,"Adding interprocedural summary : ");
567  print_entities(set_to_list(at_call_site));
568  fprintf(stderr,"\n");
569  }
570  set_free(at_call_site);
571  }
572  }
573 }
574 
576  //pips_user_warning("Unimplemented !! Results may be wrong...\n");
577  pips_user_error("Please restructure your input source code.\n");
578 }
579 
581  instruction i;
582 
583  /* Compute "copy from" sets for the instruction : recursion */
584  switch(instruction_tag( i = statement_instruction( st ))) {
587  break;
588  case is_instruction_test:
590  break;
591  case is_instruction_loop:
593  break;
596  break;
599  break;
600  case is_instruction_call:
602  break;
605  if(expression_call_p(e)) {
607  } else {
608  pips_user_warning("Unsupported stmt expression : ");
609  print_expression(e);
610  fprintf(stderr,"\n");
611  // Just propagate then...
612  set copy_from_in = COPY_FROM_IN( st );
613  set copy_from_out = COPY_FROM_OUT( st );
614  set_assign(copy_from_out, copy_from_in);
615  }
616  break;
617  }
618  case is_instruction_goto:
619  pips_internal_error("Unexpected tag %d\n", i);
620  break;
623  break;
624  default:
625  pips_internal_error("Unknown tag %d\n", instruction_tag(i) );
626  }
627 
628  ifdebug(4) {
629  fprintf(stderr,
630  "** stmt (%d) associated copy from : **\n",
631  (int)statement_ordering(st));
632  fprintf(stderr, "*\n* OUT : ");
633  {
634  string str = concatenate("Copy from out : ", NULL);
636  FOREACH(entity, e, t_from) {
637  fprintf(stderr, "%s ", entity_name(e));
638  str = concatenate(str, " ", entity_local_name(e), NULL);
639  }
640  str = concatenate(str, "\n", NULL);
643  }
644  fprintf(stderr, "*\n**********************************\n");
645 
646  fprintf(stderr, "* IN : ");
647  {
648  string str = concatenate("Copy from in : ", NULL);
650  FOREACH(entity, e, t_from) {
651  fprintf(stderr, "%s ", entity_name(e));
652  str = concatenate(str, " ", entity_local_name(e), NULL);
653  }
654  str = concatenate(str, "\n", NULL);
657  }
658  fprintf(stderr, "*\n**********************************\n");
659  }
660 
661 }
662 
663 /****************************************************************
664  * COPY TO
665  */
666 
667 static void copy_to_statement(statement st);
668 
669 static void copy_to_block(statement st, list sts) {
670  /* The initial out for the block */
671  set copy_to_out = MAKE_SET();
672  set_assign(copy_to_out, COPY_TO_OUT( st ));
673  list sts_reverse = gen_nreverse(gen_copy_seq(sts));
674  /* loop over statements inside the block */
675  FOREACH( statement, one, sts_reverse ) {
676  /* propagate "out" sets */
677  set_assign(COPY_TO_OUT( one ), copy_to_out);
678 
679  /* Compute the "copy to" for this statement */
680  copy_to_statement(one);
681 
682  /* Get the outs for next statement */
683  set_assign(copy_to_out, COPY_TO_IN( one ));
684 
685  /* This is a non necessary optimisation, the set is just smaller with */
686 // set_difference(copy_to_out, copy_to_out, COPY_FROM_IN(one));
687  }
688 
689  /* The outs for the whole block */
690  set_assign(COPY_TO_IN( st ), copy_to_out);
691 
692  /* FIXME : free sts_reverse list && copy_to_out*/
693 
694 }
695 static void copy_to_test(statement st, test t) {
696  /* Compute true branch */
699 
700  /* Compute false branch */
703 
704 
705  /* Compute "in" sets for the test */
706  set copy_to_in = COPY_TO_IN( st );
707 
709 
710  ifdebug(6) {
711  pips_debug(6,"Handling copy to for test expression : ");
713  fprintf(stderr,"\n");
714  }
715 
716  // We remove from "copy to" what is used by the test condition
719  if(entity_array_p(e_used)) {
720  pips_debug(6,"Removing %s from copy_in\n",entity_name(e_used));
721  set_del_element(copy_to_in, copy_to_in, e_used);
722  }
723  }
724 
725 
726 
727 }
729  /* Compute "out" sets for the loop body */
730  set body_out = COPY_TO_OUT(body);
731  set_union(body_out,
732  COPY_TO_OUT( st ),
733  COPY_TO_IN( body ));
734 
735  /* Save result */
736  set tmp = MAKE_SET();
737  set_assign(tmp,body_out);
738 
739  /* Compute loop body */
740  copy_to_statement(body);
741 
742  /* Fix point */
743  set_union(body_out ,
744  COPY_TO_OUT( st ),
745  COPY_TO_IN( body ));
746  if(!set_equal_p(tmp,body_out)) {
747  set_free(tmp);
748  return copy_to_all_kind_of_loop(st,body);
749  }
750  set_free(tmp);
751 
752 
753  /* Compute "in" sets for the loop */
754  if(true) { //loop_executed_once_p(st, l)) {
755  pips_debug(1,"Loop executed once !\n");
756  /* Body is always done at least one time */
757  set_assign(COPY_TO_IN( st ), COPY_TO_IN( body ));
758  } else {
759  pips_debug(1,"Loop not executed once :-( !\n");
760  /* Body is not always done */
761  set_intersection(COPY_TO_IN( st ), COPY_TO_IN( body ), COPY_TO_OUT( st ));
762  }
763 
764 
765 
766 
767 }
768 static void copy_to_loop(statement st, loop l) {
769  statement body = loop_body(l);
770  copy_to_all_kind_of_loop(st, body);
771 }
773  statement body = whileloop_body(l);
774  copy_to_all_kind_of_loop(st, body);
775 }
776 static void copy_to_forloop(statement st, forloop l) {
777  statement body = forloop_body(l);
778  copy_to_all_kind_of_loop(st, body);
779 }
780 static void copy_to_call(statement st, call c) {
782  const char* func_name = entity_local_name(callee);
783 
784  /* The initial */
785  set copy_to_in = COPY_TO_IN( st );
786  set copy_to_out = COPY_TO_OUT( st );
787 
788  /* The ins are initially the out minus CopyFrom*/
789  set_assign(copy_to_in, copy_to_out);
790  if(is_a_kernel(func_name)) {
791  pips_debug(3,"%s is a Kernel !\n",
792  func_name);
793  // it's a kernel call !!
794  // Let's add the "region in" and "region out" to copy_to set !
795  list l_in = load_statement_in_regions(st);
796  FOREACH(EFFECT, eff, l_in )
797  {
799  if(entity_array_p(e_used)) {
800  pips_debug(6,"Adding in %s into copy_in\n",entity_name(e_used));
801  copy_to_in = set_add_element(copy_to_in, copy_to_in, e_used);
802  }
803  }
804  list l_out = load_statement_out_regions(st);
805  FOREACH(EFFECT, eff, l_out )
806  {
808  if(entity_array_p(e_used)) {
810 
811  if(!array_must_fully_written_by_regions_p(e_used,lreg)) {
812  pips_debug(6,"Adding written %s into copy_in\n",entity_name(e_used));
813  copy_to_in = set_add_element(copy_to_in, copy_to_in, e_used);
814  } else {
815  pips_debug(6,"Do not add %s into copy_in because fully overwritten\n",
816  entity_name(e_used));
817  }
818  }
819  }
820  } else {
821  // Standard call (not a kernel)
822  pips_debug(3,"%s is a simple call\n",
823  func_name);
824  // We remove from "copy to" what is written by this statement
826 // if(effect_write_p(eff)) { BUGGY at that time ! it breaks hoisting transfers out of loop... the scheme is broken by design !
828  ifdebug(6) {
829  if(entity_array_p(e_used)) {
830  pips_debug(6,"Removing %s from copy_in\n",entity_name(e_used));
831  }
832  }
833  copy_to_in = set_del_element(copy_to_in, copy_to_in, e_used);
834 // }
835  }
836 
837 
838  // We add the inter-procedural results for copy in, but not for intrinsics
839  if(user_call_p(c)) { // Ignoring intrinsics
840  set at_call_site = interprocedural_mapping(DBR_KERNEL_COPY_IN,c);
841  copy_to_in = set_union(copy_to_in, at_call_site, copy_to_in);
842  set_free(at_call_site);
843  }
844 
845  }
846  // copy_to_in = set_difference(copy_to_in, copy_to_in, COPY_FROM_IN(st));
847 }
848 
850  //pips_user_warning("Unimplemented !! Results may be wrong...\n");
851  pips_user_error("Please restructure your source code.\n");
852 }
853 
854 static void get_written_entities(statement s, set written_entities) {
856  if(effect_write_p(eff) && store_effect_p(eff)) {
858  set_add_element(written_entities,written_entities,e_used);
859  }
860  }
861 }
862 
863 static void copy_to_statement(statement st) {
864  instruction i;
865 
866  /* Compute "copy from" sets for the instruction : recursion */
867  switch(instruction_tag( i = statement_instruction( st ))) {
870  break;
871  case is_instruction_test:
872  copy_to_test(st, instruction_test( i ));
873  break;
874  case is_instruction_loop:
875  copy_to_loop(st, instruction_loop( i ));
876  break;
879  break;
882  break;
883  case is_instruction_call:
884  copy_to_call(st, instruction_call( i ));
885  break;
888  if(expression_call_p(e)) {
890  } else {
891  pips_user_warning("Unsupported stmt expression : ");
892  print_expression(e);
893  fprintf(stderr,"\n");
894  // Just propagate then...
895  set copy_to_in = COPY_TO_IN( st );
896  set copy_to_out = COPY_TO_OUT( st );
897  /* The ins are initially the out minus CopyFrom*/
898  set_assign(copy_to_in, copy_to_out);
899  }
900  break;
901  }
902  case is_instruction_goto:
903  pips_internal_error("Unexpected instruction tag %d\n", i);
904  break;
907  break;
908  default:
909  pips_internal_error("Unknown tag %d\n", instruction_tag(i) );
910  }
911 
912 
913  // We remove from "copy to out" what is not written by this statement
914  set allowed_to_copy_to= MAKE_SET();
915  gen_context_recurse(st, allowed_to_copy_to,
917  ifdebug(4) {
918  pips_debug(4,"Removing from copy_to_out what is not written here : ");
919  set removed = MAKE_SET();
920  set_difference(removed,COPY_TO_OUT(st),allowed_to_copy_to);
922  FOREACH(entity, e, t_to) {
923  fprintf(stderr, "%s ", entity_name(e));
924  }
925  fprintf(stderr, "\n");
926  }
927  set_intersection(COPY_TO_OUT(st),COPY_TO_OUT(st),allowed_to_copy_to);
928  set_free(allowed_to_copy_to);
929 
930 
931  ifdebug(4) {
932  fprintf(stderr,
933  "** stmt (%d) associated copy to : **\n",
934  (int)statement_ordering(st));
935  fprintf(stderr, "*\n* OUT : ");
936  {
937  string str = concatenate("Copy to out : ", NULL);
939  FOREACH(entity, e, t_to) {
940  fprintf(stderr, "%s ", entity_name(e));
941  str = concatenate(str, " ", entity_local_name(e), NULL);
942  }
943  str = concatenate(str, "\n", NULL);
946  }
947  fprintf(stderr, "* IN : ");
948  {
949  string str = concatenate("Copy to in : ", NULL);
951  FOREACH(entity, e, t_to) {
952  fprintf(stderr, "%s ", entity_name(e));
953  str = concatenate(str, " ", entity_local_name(e), NULL);
954  }
955  str = concatenate(str, "\n", NULL);
958  }
959  fprintf(stderr, "*\n**********************************\n");
960  }
961 
962 
963 }
964 
965 /****************************************************************
966  * GENERATE TRANSFERT
967  */
968 
969 static void transfert_statement(statement st,
970  set already_transfered_to,
971  set already_transfered_from,
972  set array_to_transfer_to_after,
973  set array_to_transfer_from_before);
974 
976  list sts,
977  set already_transfered,
978  set already_transfered_from) {
979 
980  pips_debug(4,"Entering transfert_block\n");
981 
982  /* loop over statements inside the block */
983  for (list current = (sts); !ENDP(current); POP(current)) {
984  statement one = STATEMENT(CAR(current));
985 
986  // These are here to record what a statement require to transfer
987  // We generate transfers only in sequence
988  set transfert_to = MAKE_SET();
989  set transfert_from = MAKE_SET();
990 
991  /* Compute the transfer for this statement */
993  already_transfered,
994  already_transfered_from,
995  transfert_to,
996  transfert_from);
997  // Really insert the transfers statement
998  list t_from = set_to_sorted_list(transfert_from,(gen_cmp_func_t)compare_entities);
999  FOREACH(entity, e_from, t_from) {
1000  statement new_st_from = make_dma_transfert(e_from, dma_store);
1001  CDR(current) = CONS(statement,one,CDR(current));
1002  CAR(current).e = new_st_from;
1003  POP(current);
1004  }
1005  gen_free_list(t_from);
1006 
1007 
1009  FOREACH(entity, e_to, t_to) {
1010  statement new_st_to = make_dma_transfert(e_to, dma_load);
1011  CDR(current) = CONS(statement,new_st_to,CDR(current));
1012  POP(current);
1013  }
1014  gen_free_list(t_to);
1015  }
1016 
1017 
1018 }
1020  test t,
1021  set already_transfered,
1022  set already_transfered_from,
1023  set transfert_to,
1024  set transfert_from) {
1025  set already_transfered_from_tmp = set_make(set_pointer);
1026  set already_transfered_tmp = set_make(set_pointer);
1027  set transfert_to_tmp = set_make(set_pointer);
1028  set transfert_from_tmp = set_make(set_pointer);
1029 
1030  set_assign(already_transfered_from_tmp,already_transfered_from);
1031  set_assign(already_transfered_tmp,already_transfered);
1032  set_assign(transfert_to_tmp,transfert_to);
1033  set_assign(transfert_from_tmp,transfert_from);
1034 
1035 
1037  already_transfered_tmp,
1038  already_transfered_from_tmp,
1039  transfert_to_tmp,
1040  transfert_from_tmp);
1041 
1042 
1043  set_assign(already_transfered_from_tmp,already_transfered_from);
1044  set_assign(already_transfered_tmp,already_transfered);
1045  set_assign(transfert_to_tmp,transfert_to);
1046  set_assign(transfert_from_tmp,transfert_from);
1047 
1049  already_transfered_tmp,
1050  already_transfered_from_tmp,
1051  transfert_to_tmp,
1052  transfert_from_tmp);
1053 
1054 
1055 }
1056 
1057 
1058 
1060  loop l,
1061  set already_transfered,
1062  set already_transfered_from,
1063  set transfert_to,
1064  set transfert_from) {
1065  statement body = loop_body(l);
1066 
1067  /* Compute loop body */
1068  transfert_statement(body,
1069  already_transfered,
1070  already_transfered_from,
1071  transfert_to,
1072  transfert_from);
1073 
1074 
1075  /*
1076  * At the end of a loop, we check that any transfer that need to be done
1077  */
1078 
1079  // Retrieve the last statement of the loop body
1080  set last_copy_from = set_undefined;
1081  if (!statement_sequence_p(body)) {
1082  last_copy_from = COPY_FROM_OUT(body);
1083  } else {
1084  // FC: apparently last_copy_from may not be always assigned...
1086  set copy_from = COPY_FROM_OUT(s);
1087  if (copy_from && !set_undefined_p(copy_from))
1088  last_copy_from = copy_from;
1089  }
1090  }
1091 
1092  /*
1093  * Compute the set of entity that are not on the GPU at the begin of the loop
1094  * but need a copy-out at the end, after the last statement
1095  */
1096  set fixed_transfert_from = MAKE_SET();
1097  set_difference(fixed_transfert_from,last_copy_from,COPY_FROM_OUT(body));
1098  list t_from = set_to_sorted_list(fixed_transfert_from,(gen_cmp_func_t)compare_entities);
1099  set_free(fixed_transfert_from);
1100  // Insert transfers at the end of the loop !
1101  FOREACH(entity, e_from, t_from) {
1102  insert_statement(body,make_dma_transfert(e_from, dma_store),false);
1103  }
1104 
1105 
1106 }
1107 
1109  whileloop l,
1110  set already_transfered,
1111  set already_transfered_from,
1112  set transfert_to,
1113  set transfert_from) {
1114  statement body = whileloop_body(l);
1115 
1116  /* Compute loop body */
1117  transfert_statement(body,
1118  already_transfered,
1119  already_transfered_from,
1120  transfert_to,
1121  transfert_from);
1122 }
1124  forloop l,
1125  set already_transfered,
1126  set already_transfered_from,
1127  set transfert_to,
1128  set transfert_from) {
1129  statement body = forloop_body(l);
1130 
1131  /* Compute loop body */
1132  transfert_statement(body,
1133  already_transfered,
1134  already_transfered_from,
1135  transfert_to,
1136  transfert_from);
1137 }
1139  _UNUSED_ call c,
1140  _UNUSED_ set already_transfered,
1141  _UNUSED_ set already_transfered_from) {
1142 }
1143 
1146  _UNUSED_ set already_transfered,
1147  _UNUSED_ set already_transfered_from) {
1148  //pips_user_warning("Unimplemented !! Results may be wrong...\n");
1149  pips_user_error("Unstructured are not processed. Please structure your input code.\n");
1150 }
1151 
1153  set already_transfered_to,
1154  set already_transfered_from,
1155  set array_to_transfer_to_after,
1156  set array_to_transfer_from_before) {
1157 
1159 
1160  set transferts_to = MAKE_SET();
1161  set_difference(transferts_to, COPY_TO_OUT(st), COPY_TO_IN(st));
1162  set_difference(transferts_to, transferts_to, COPY_FROM_OUT(st));
1163  set_difference(transferts_to, transferts_to, already_transfered_to);
1164 
1165  // We remove from "transfers_to" what is not written by this statement
1166  set allowed_to_transfer_to= MAKE_SET();
1167  gen_context_recurse(st, allowed_to_transfer_to,
1169  ifdebug(4) {
1170  pips_debug(4,"Removing from transfer_to what is not written here : ");
1171  set removed = MAKE_SET();
1172  set_difference(removed,transferts_to,allowed_to_transfer_to);
1174  FOREACH(entity, e, t_to) {
1175  fprintf(stderr, "%s ", entity_name(e));
1176  }
1177  fprintf(stderr, "\n");
1178  }
1179  set_intersection(transferts_to,transferts_to,allowed_to_transfer_to);
1180  set_free(allowed_to_transfer_to);
1181 
1182 
1183  SET_FOREACH(entity, e, transferts_to) {
1184  set_add_element(already_transfered_to, already_transfered_to, e);
1185  set_add_element(array_to_transfer_to_after, array_to_transfer_to_after, e);
1186 
1187  ifdebug(2) {
1188  string str = strdup(concatenate("Transfert to accel : ",
1189  entity_local_name(e),
1190  "\n",
1191  NULL));
1192  pips_debug(4,"(%zd) %s",statement_number(st),concatenate("Inserting :",str,"\n",NULL));
1194  free(str);
1195  }
1196  }
1197 
1198  set transferts_from = MAKE_SET();
1199  set_difference(transferts_from, COPY_FROM_IN(st), COPY_FROM_OUT(st));
1200  set_difference(transferts_from, transferts_from, COPY_TO_IN(st));
1201  set_difference(transferts_from, transferts_from, already_transfered_from);
1202 
1203  {
1204  SET_FOREACH(entity, e, transferts_from)
1205  {
1206  set_add_element(already_transfered_from, already_transfered_from, e);
1207  set_add_element(array_to_transfer_from_before,
1208  array_to_transfer_from_before,
1209  e);
1210  ifdebug(2) {
1211  string str = strdup(concatenate("Transfert from accel : ",
1212  entity_local_name(e),
1213  "\n",
1214  NULL));
1215  pips_debug(4,"Inserting : %s\n",str);
1217  free(str);
1218  }
1219  }
1220  }
1221 
1222  /* Compute "copy from" sets for the instruction : recursion */
1223  switch(instruction_tag(i)) {
1224  case is_instruction_block:
1225  transfert_block(st,
1226  instruction_block( i ),
1227  already_transfered_to,
1228  already_transfered_from);
1229  break;
1230  case is_instruction_test:
1231  transfert_test(st,
1232  instruction_test( i ),
1233  already_transfered_to,
1234  already_transfered_from,
1235  array_to_transfer_to_after,
1236  array_to_transfer_from_before);
1237  break;
1238  case is_instruction_loop:
1239  transfert_loop(st,
1240  instruction_loop( i ),
1241  already_transfered_to,
1242  already_transfered_from,
1243  array_to_transfer_to_after,
1244  array_to_transfer_from_before);
1245  break;
1248  instruction_whileloop( i ),
1249  already_transfered_to,
1250  already_transfered_from,
1251  array_to_transfer_to_after,
1252  array_to_transfer_from_before);
1253  break;
1255  transfert_forloop(st,
1256  instruction_forloop( i ),
1257  already_transfered_to,
1258  already_transfered_from,
1259  array_to_transfer_to_after,
1260  array_to_transfer_from_before);
1261  break;
1262  case is_instruction_call:
1263  transfert_call(st,
1264  instruction_call( i ),
1265  already_transfered_to,
1266  already_transfered_from);
1267  break;
1269  /* The second argument is not used */
1270  transfert_call(st,
1272  already_transfered_to,
1273  already_transfered_from);
1274  break;
1275  case is_instruction_goto:
1276  pips_internal_error("Unexpected instruction tag %d: GOTO\n", i);
1277  break;
1281  already_transfered_to,
1282  already_transfered_from);
1283  break;
1284  default:
1285  pips_internal_error("Unknown tag %d\n", instruction_tag(i) );
1286  }
1287 
1288 
1289 
1290  set killed_transfer = MAKE_SET();
1291  set_difference(killed_transfer, COPY_TO_OUT(st), COPY_TO_IN(st));
1292  set_difference(already_transfered_to, already_transfered_to, killed_transfer);
1293  set_difference(killed_transfer, COPY_FROM_IN(st), COPY_FROM_OUT(st));
1294  set_difference(already_transfered_from,
1295  already_transfered_from,
1296  killed_transfer);
1297  set_free(killed_transfer);
1298 
1299 }
1300 
1302  statement module_stat;
1303 
1305  module_name,
1306  true));
1307  module_stat = get_current_module_statement();
1309  /* set_entity_to_size(); should be performed at the workspace level */
1310 
1311  debug_on("KERNEL_DATA_MAPPING_DEBUG_LEVEL");
1312 
1313  string pe = db_get_memory_resource(DBR_PROPER_EFFECTS, module_name, true);
1315 
1316  /* out regions */
1317  string or = db_get_memory_resource(DBR_OUT_REGIONS, module_name, true);
1319 
1320  /* in regions */
1321  string ir = db_get_memory_resource(DBR_IN_REGIONS, module_name, true);
1323 
1324  /* preconditions */
1325  string precond = db_get_memory_resource(DBR_PRECONDITIONS, module_name, true);
1327 
1328  transfert_statement(module_stat, MAKE_SET(), MAKE_SET(), NULL, NULL);
1329 
1330  DB_PUT_MEMORY_RESOURCE(DBR_CODE,
1331  module_name,
1332  module_stat);
1333 
1336  reset_in_effects();
1340 
1341  return true;
1342 }
1343 
1345  statement module_stat;
1346 
1348  module_name,
1349  true));
1350  module_stat = get_current_module_statement();
1352  /* set_entity_to_size(); should be performed at the workspace level */
1353 
1354  debug_on("KERNEL_DATA_MAPPING_DEBUG_LEVEL");
1355 
1356 
1357  /* regions */
1358  string region = db_get_memory_resource(DBR_REGIONS, module_name, true);
1360 
1361 
1362  /* out regions */
1363  string or = db_get_memory_resource(DBR_OUT_REGIONS, module_name, true);
1365 
1366  /* in regions */
1367  string ir = db_get_memory_resource(DBR_IN_REGIONS, module_name, true);
1369 
1370  /* preconditions */
1371  string precond = db_get_memory_resource(DBR_PRECONDITIONS, module_name, true);
1373 
1374  /* preconditions */
1375  string cumu = db_get_memory_resource(DBR_CUMULATED_EFFECTS, module_name, true);
1377 
1378  // Stuff for ... ?
1380 
1381 
1382  /* Initialize global hashtables */
1387 
1388  /* Initialize set for each statement */
1390 
1391  /* Run the pass except if current module is a kernel */
1392  if(!is_a_kernel(module_name)) {
1393  copy_from_statement(module_stat);
1394  copy_to_statement(module_stat);
1395  // Is it a bad hack ? Should we need a fix point here ?
1396  copy_from_statement(module_stat);
1397 
1398  transfert_statement(module_stat, MAKE_SET(), MAKE_SET(), MAKE_SET(), MAKE_SET());
1399  }
1400 
1401  ifdebug(1) {
1402  pips_debug(1,"Interprocedural summary for %s :\n To :",module_name);
1403  print_entities(set_to_list(COPY_TO_IN(module_stat)));
1404  fprintf(stderr,"\n From :");
1405  print_entities(set_to_list(COPY_FROM_OUT(module_stat)));
1406  fprintf(stderr,"\n");
1407  }
1408 
1409  DB_PUT_MEMORY_RESOURCE(DBR_CODE,
1410  module_name,
1411  module_stat);
1412 
1413  DB_PUT_MEMORY_RESOURCE(DBR_KERNEL_COPY_IN,
1414  module_name,
1415  make_memory_mapping(COPY_TO_IN(module_stat)));
1416  DB_PUT_MEMORY_RESOURCE(DBR_KERNEL_COPY_OUT,
1417  module_name,
1418  make_memory_mapping(COPY_FROM_OUT(module_stat)));
1419 
1420 #define TABLE_FREE(t) \
1421  {HASH_MAP( k, v, {set_free( (set)v ) ;}, t ) ; hash_table_free(t);}
1422 
1423  // TABLE_FREE(copies_from_in);
1424  // TABLE_FREE(copies_from_out);
1425 
1428  reset_in_effects();
1434 
1435  return true;
1436 }
1437 
1438 
1439 
1440 
1441 
1442 static entity wrapper_function = NULL;
1443 
1444 
1445 static void wrap_argument(syntax s) {
1446  if(syntax_reference_p(s)
1449 
1450 
1451 /*
1452  sizeofexpression size_of = make_sizeofexpression_expression(transfer_size);
1453  expression size_of_e;
1454  size_of_e = make_expression(make_syntax_sizeofexpression(size_of),
1455  normalized_undefined);
1456 */
1457  syntax new_ref = copy_syntax(s);
1459  list args = make_expression_list(make_expression(new_ref,
1461  makeTransfertSizeExpression(e)/*size_of_e*/);
1463 
1465  }
1466 
1467 }
1468 
1469 static void wrap_call_argument(call c, const char* module_name) {
1470  if(!call_intrinsic_p(c)
1472 
1473  list args = call_arguments(c);
1474  for (expression e; !ENDP(args); POP(args)) {
1475  e = EXPRESSION(CAR(args));
1477  }
1478 
1479  }
1480 }
1481 
1482 
1483 /**
1484  * This pass will wrap kernel arguments in a call to a wrapper function.
1485  */
1487 
1489 
1490  debug_on("WRAP_KERNEL_ARGUMENT_DEBUG_LEVEL");
1491 
1492  callees callers = (callees)db_get_memory_resource(DBR_CALLERS,
1493  module_name,
1494  true);
1495 
1496  // Get the wrapper function
1497  const char* function_name = get_string_property("WRAP_KERNEL_ARGUMENT_FUNCTION_NAME");
1498  wrapper_function = module_name_to_entity(function_name);
1501  = make_empty_subroutine(function_name,
1502  copy_language(module_language(kernel_entity)));
1503  pips_user_warning("Cannot find \"%s\" method. Are you sure you have set\n"
1504  "WRAP_KERNEL_ARGUMENT_FUNCTION_NAME"
1505  "to a defined entity and added the correct .c file?\n",function_name);
1506  }
1507 
1508 
1509 
1510 
1512  /* prelude */
1515  caller_name,
1516  true));
1517 
1518  /*do the job */
1521  /* validate */
1525 
1526  /*postlude*/
1529  }
1530 
1531  return true;
1532 }
1533 
float a2sf[2] __attribute__((aligned(16)))
USER generates a user error (i.e., non fatal) by printing the given MSG according to the FMT.
Definition: 3dnow.h:3
approximation make_approximation_exact(void)
Definition: effects.c:185
memory_mapping make_memory_mapping(set a)
void free_normalized(normalized p)
Definition: ri.c:1407
call make_call(entity a1, list a2)
Definition: ri.c:269
expression make_expression(syntax a1, normalized a2)
Definition: ri.c:886
type make_type_variable(variable _field_)
Definition: ri.c:2715
syntax make_syntax_sizeofexpression(sizeofexpression _field_)
Definition: ri.c:2506
basic copy_basic(basic p)
BASIC.
Definition: ri.c:104
language copy_language(language p)
LANGUAGE.
Definition: ri.c:1202
sizeofexpression make_sizeofexpression_type(type _field_)
Definition: ri.c:2177
variable make_variable(basic a1, list a2, list a3)
Definition: ri.c:2895
instruction make_instruction_call(call _field_)
Definition: ri.c:1184
syntax copy_syntax(syntax p)
SYNTAX.
Definition: ri.c:2442
region_to_dma_switch
@ dma_store
@ dma_load
static const char * caller_name
Definition: alias_check.c:122
static entity callee
Definition: alias_pairs.c:62
void const char const char const int
callees compute_callees(const statement stat)
Recompute the callees of a module statement.
Definition: callgraph.c:355
#define region_empty_p(reg)
#define region
simulation of the type region
#define region_exact_p(reg)
list region_sup_difference(region reg1, region reg2)
list region_sup_difference(effect reg1, reg2) input : two regions output : a list of regions containi...
effect entity_whole_region(entity, action)
Psysteme entity_declaration_sc(entity)
void region_exact_projection_along_variables(effect, list)
void region_exact_projection_along_variables(effect reg, list l_var) input : a region and a list of v...
list load_proper_rw_effects_list(statement)
void reset_out_effects(void)
void reset_proper_rw_effects(void)
void set_proper_rw_effects(statement_effects)
void set_cumulated_rw_effects(statement_effects)
void set_out_effects(statement_effects)
void set_in_effects(statement_effects)
void reset_in_effects(void)
list load_statement_out_regions(statement)
list load_statement_in_regions(statement)
void reset_cumulated_rw_effects(void)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define effect_write_p(eff)
action make_action_write_memory(void)
To ease the extension of action with action_kind.
Definition: effects.c:1011
bool store_effect_p(effect)
Definition: effects.c:1062
#define descriptor_convex_p(x)
Definition: effects.h:599
#define effect_descriptor(x)
Definition: effects.h:646
#define descriptor_convex(x)
Definition: effects.h:601
#define effect_approximation(x)
Definition: effects.h:644
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
char * get_string_property(const char *)
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
Definition: genC.h:285
#define STRING(x)
Definition: genC.h:87
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
void free(void *)
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
Definition: statement.c:597
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
bool gen_true2(__attribute__((unused)) gen_chunk *u1, __attribute__((unused)) void *u2)
Definition: genClib.c:2785
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
void gen_remove(list *cpp, const void *o)
remove all occurences of item o from list *cpp, which is thus modified.
Definition: list.c:685
#define 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
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
#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 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 CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
Definition: database.c:755
#define DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
Definition: pipsdbm-local.h:66
sequence statement_sequence(statement)
Get the sequence of a statement sequence.
Definition: statement.c:1328
bool empty_statement_or_continue_without_comment_p(statement)
Return true if the statement is an empty instruction block or a continue without comments or without ...
Definition: statement.c:497
bool statement_sequence_p(statement)
Statement classes induced from instruction type.
Definition: statement.c:335
void insert_comments_to_statement(statement, const char *)
Insert a comment string (if non empty) at the beginning of the comments of a statement.
Definition: statement.c:1916
void insert_statement(statement, statement, bool)
This is the normal entry point.
Definition: statement.c:2570
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
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
list base_to_list(Pbase base)
Most includes are centralized here.
static void get_written_entities(statement s, set written_entities)
Definition: ikernels.c:854
static void transfert_call(_UNUSED_ statement st, _UNUSED_ call c, _UNUSED_ set already_transfered, _UNUSED_ set already_transfered_from)
Definition: ikernels.c:1138
static void copy_from_forloop(statement st, forloop l)
Definition: ikernels.c:507
static void wrap_call_argument(call c, const char *module_name)
Definition: ikernels.c:1469
static bool force_renormalize(expression e)
Should be useful, but for some bullshit reason the array dimensions even for simple case like a[512][...
Definition: ikernels.c:221
static void transfert_block(_UNUSED_ statement st, list sts, set already_transfered, set already_transfered_from)
Definition: ikernels.c:975
static void force_renormalize_rwt(expression e)
Definition: ikernels.c:231
static set interprocedural_mapping(string res, call c)
Translate the interprocedural summary for a function into a set of local corresponding parameters (en...
Definition: ikernels.c:311
bool is_a_kernel(const char *func_name)
Definition: ikernels.c:369
#define INIT_STATEMENT_SIZE
Definition: ikernels.c:141
static const char * get_dma_name(enum region_to_dma_switch m, int d)
converts a region_to_dma_switch to corresponding dma name according to properties
Definition: ikernels.c:92
static void transfert_forloop(_UNUSED_ statement st, forloop l, set already_transfered, set already_transfered_from, set transfert_to, set transfert_from)
Definition: ikernels.c:1123
static void transfert_test(_UNUSED_ statement st, test t, set already_transfered, set already_transfered_from, set transfert_to, set transfert_from)
Definition: ikernels.c:1019
static void copy_to_whileloop(statement st, whileloop l)
Definition: ikernels.c:772
static expression makeTransfertSizeExpression(entity e)
Make a sizeof expression.
Definition: ikernels.c:63
#define MAKE_SET()
Macro to create set.
Definition: ikernels.c:145
#define COPY_TO_IN(st)
Definition: ikernels.c:181
static void wrap_argument(syntax s)
Definition: ikernels.c:1445
void dump_entity_set(set s)
ikernels.c
Definition: ikernels.c:209
static void copy_from_statement(statement st)
Definition: ikernels.c:580
static void copy_to_block(statement st, list sts)
Definition: ikernels.c:669
static hash_table copies_to_in
copy_to_in maps each statement to the "copy to" data that are in-coming the statement
Definition: ikernels.c:180
static void transfert_whileloop(_UNUSED_ statement st, whileloop l, set already_transfered, set already_transfered_from, set transfert_to, set transfert_from)
Definition: ikernels.c:1108
static void copy_from_whileloop(statement st, whileloop l)
Definition: ikernels.c:503
static bool array_must_fully_written_by_regions_p(entity e_used, list lreg)
Check that an array is fully written by an exact W region in a list.
Definition: ikernels.c:238
static void copy_to_all_kind_of_loop(statement st, statement body)
Definition: ikernels.c:728
static hash_table copies_to_out
copy_to_out maps each statement to the "copy to" data that are out-going from the statement
Definition: ikernels.c:195
static void copy_to_call(statement st, call c)
Definition: ikernels.c:780
static void transfert_unstructured(_UNUSED_ statement st, _UNUSED_ unstructured u, _UNUSED_ set already_transfered, _UNUSED_ set already_transfered_from)
Definition: ikernels.c:1144
static void copy_from_test(statement st, test t)
Definition: ikernels.c:411
static statement make_dma_transfert(entity e, enum region_to_dma_switch dma)
Definition: ikernels.c:110
#define COPY_FROM_OUT(st)
Definition: ikernels.c:166
static entity wrapper_function
Definition: ikernels.c:1442
static void init_one_statement(statement st)
Definition: ikernels.c:379
static void copy_to_forloop(statement st, forloop l)
Definition: ikernels.c:776
static void copy_from_call(statement st, call c)
Definition: ikernels.c:512
static void copy_from_unstructured(_UNUSED_ statement st, _UNUSED_ unstructured u)
Definition: ikernels.c:575
static void copy_to_test(statement st, test t)
Definition: ikernels.c:695
static hash_table copies_from_out
copy_from_out maps each statement to the "copy from" data that are out-going from the statement
Definition: ikernels.c:165
bool kernel_data_mapping(char *module_name)
Definition: ikernels.c:1344
bool wrap_kernel_argument(char *module_name)
This pass will wrap kernel arguments in a call to a wrapper function.
Definition: ikernels.c:1486
bool ikernel_load_store(__attribute__((unused)) char *module_name)
Definition: ikernels.c:1301
static void copy_from_all_kind_of_loop(statement st, statement body)
Definition: ikernels.c:448
static void transfert_loop(_UNUSED_ statement st, loop l, set already_transfered, set already_transfered_from, set transfert_to, set transfert_from)
Definition: ikernels.c:1059
static void transfert_statement(statement st, set already_transfered_to, set already_transfered_from, set array_to_transfer_to_after, set array_to_transfer_from_before)
Definition: ikernels.c:1152
#define COPY_FROM_IN(st)
Definition: ikernels.c:151
static void copy_from_block(statement st, cons *sts)
Definition: ikernels.c:392
static void copy_to_statement(statement st)
Definition: ikernels.c:863
#define COPY_TO_OUT(st)
Definition: ikernels.c:196
static void copy_from_loop(statement st, loop l)
Definition: ikernels.c:479
static void copy_to_unstructured(_UNUSED_ statement st, _UNUSED_ unstructured u)
Definition: ikernels.c:849
static void copy_to_loop(statement st, loop l)
Definition: ikernels.c:768
static hash_table copies_from_in
copy_from_in maps each statement to the "copy from" data that are in-coming the statement
Definition: ikernels.c:150
struct _newgen_struct_memory_mapping_ * memory_mapping
#define memory_mapping_map(x)
#define debug_on(env)
Definition: misc-local.h:157
#define _UNUSED_
Definition: misc-local.h:232
#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_user_warning
Definition: misc-local.h:146
#define asprintf
Definition: misc-local.h:225
#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
#define pips_user_error
Definition: misc-local.h:147
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
@ 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
#define same_string_p(s1, s2)
set set_del_element(set, const set, const void *)
Definition: set.c:265
set set_intersection(set, const set, const set)
Definition: set.c:229
#define set_undefined
Definition: newgen_set.h:48
list set_to_list(const set)
create a list from a set the set is not freed
Definition: set.c:436
list set_to_sorted_list(const set, gen_cmp_func_t)
Definition: set.c:447
set set_assign(set, const set)
Assign a set with the content of another set.
Definition: set.c:129
bool set_equal_p(const set, const set)
returns whether s1 == s2
Definition: set.c:316
set set_difference(set, const set, const set)
Definition: set.c:256
#define SET_FOREACH(type_name, the_item, the_set)
enumerate set elements in their internal order.
Definition: newgen_set.h:78
void set_free(set)
Definition: set.c:332
bool set_belong_p(const set, const void *)
Definition: set.c:194
set set_union(set, const set, const set)
Definition: set.c:211
@ set_pointer
Definition: newgen_set.h:44
#define set_undefined_p(s)
Definition: newgen_set.h:49
set set_make(set_type)
Create an empty set of any type but hash_private.
Definition: set.c:102
set set_add_element(set, const set, const void *)
Definition: set.c:152
int(* gen_cmp_func_t)(const void *, const void *)
Definition: newgen_types.h:114
normalized NormalizeExpression(expression e)
normalize.c
Definition: normalize.c:81
void print_syntax(syntax s)
Definition: expression.c:121
void print_expression(expression e)
no file descriptor is passed to make is easier to use in a debugging stage.
Definition: expression.c:58
#define print_region(x)
Definition: print.c:343
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
#define make_expression_list(stats...)
#define statement_block_p(stat)
#define call_intrinsic_p(C)
#define is_instruction_block
soft block->sequence transition
#define module_language(e)
implemented as a macro to allow lhs
#define instruction_block(i)
#define MULTIPLY_OPERATOR_NAME
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
int compare_entities(const entity *pe1, const entity *pe2)
Comparison function for qsort.
Definition: entity.c:1328
bool entity_array_p(entity e)
Is e a variable with an array type?
Definition: entity.c:754
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
entity local_name_to_top_level_entity(const char *n)
This function try to find a top-level entity from a local name.
Definition: entity.c:1450
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
entity make_empty_subroutine(const char *name, language l)
Definition: entity.c:268
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
void print_entities(list l)
Definition: entity.c:167
bool top_level_entity_p(entity e)
Check if the scope of entity e is global.
Definition: entity.c:1130
entity find_ith_formal_parameter(entity the_fnct, int rank)
This function gives back the ith formal parameter, which is found in the declarations of a call or a ...
Definition: entity.c:1863
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
bool expression_call_p(expression e)
Definition: expression.c:415
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
call expression_call(expression e)
Definition: expression.c:445
bool user_call_p(call c)
Test if a call is a user call.
Definition: expression.c:4361
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
list module_formal_parameters(entity func)
list module_formal_parameters(entity func) input : an entity representing a function.
Definition: module.c:327
expression SizeOfDimensions(list)
computes the product of all dimensions in dims
Definition: size.c:522
#define loop_body(x)
Definition: ri.h:1644
#define normalized_undefined
Definition: ri.h:1745
struct _newgen_struct_callees_ * callees
Definition: ri.h:55
#define syntax_reference_p(x)
Definition: ri.h:2728
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154
#define syntax_reference(x)
Definition: ri.h:2730
#define syntax_tag(x)
Definition: ri.h:2727
#define call_function(x)
Definition: ri.h:709
#define callees_callees(x)
Definition: ri.h:675
#define reference_variable(x)
Definition: ri.h:2326
#define instruction_loop(x)
Definition: ri.h:1520
#define statement_ordering(x)
Definition: ri.h:2454
#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
@ is_syntax_call
Definition: ri.h:2693
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define entity_undefined_p(x)
Definition: ri.h:2762
@ is_instruction_goto
Definition: ri.h:1473
@ is_instruction_unstructured
Definition: ri.h:1475
@ is_instruction_whileloop
Definition: ri.h:1472
@ is_instruction_expression
Definition: ri.h:1478
@ is_instruction_test
Definition: ri.h:1470
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_forloop
Definition: ri.h:1477
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define entity_name(x)
Definition: ri.h:2790
#define expression_normalized(x)
Definition: ri.h:1249
#define test_true(x)
Definition: ri.h:2835
#define sequence_statements(x)
Definition: ri.h:2360
#define dimension_upper(x)
Definition: ri.h:982
#define reference_indices(x)
Definition: ri.h:2328
#define instruction_forloop(x)
Definition: ri.h:1538
#define syntax_call(x)
Definition: ri.h:2736
#define instruction_expression(x)
Definition: ri.h:1541
#define test_condition(x)
Definition: ri.h:2833
#define instruction_whileloop(x)
Definition: ri.h:1523
#define variable_dimensions(x)
Definition: ri.h:3122
#define whileloop_body(x)
Definition: ri.h:3162
#define statement_instruction(x)
Definition: ri.h:2458
#define instruction_call(x)
Definition: ri.h:1529
#define call_arguments(x)
Definition: ri.h:711
#define instruction_test(x)
Definition: ri.h:1517
#define normalized_undefined_p(x)
Definition: ri.h:1746
#define entity_type(x)
Definition: ri.h:2792
#define statement_number(x)
Definition: ri.h:2452
#define expression_syntax(x)
Definition: ri.h:1247
#define type_variable_p(x)
Definition: ri.h:2947
#define forloop_body(x)
Definition: ri.h:1372
#define instruction_unstructured(x)
Definition: ri.h:1532
#define variable_basic(x)
Definition: ri.h:3120
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
#define syntax_domain
newgen_synchronization_domain_defined
Definition: ri.h:402
Psysteme sc_safe_append(Psysteme s1, Psysteme s2)
Psysteme sc_safe_append(Psysteme s1, Psysteme s2) input : output : calcul de l'intersection des polye...
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
Psysteme sc_safe_normalize(Psysteme ps)
Psysteme sc_safe_normalize(Psysteme ps) output : ps, normalized.
void module_to_value_mappings(entity m)
void module_to_value_mappings(entity m): build hash tables between variables and values (old,...
Definition: mappings.c:624
void reset_precondition_map(void)
void set_precondition_map(statement_mapping)
#define ifdebug(n)
Definition: sg.c:47
static entity array
static size_t current
Definition: string.c:115
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
void free_value_mappings(void)
Normal call to free the mappings.
Definition: value.c:1212
@ empty
b1 < bj -> h1/hj = empty
Definition: union-local.h:64
void AddEntityToModuleCompilationUnit(entity e, entity module)
Definition: module.c:301