PIPS
copy_value_of_write.c
Go to the documentation of this file.
1 /*
2 
3  $Id$
4 
5  Copyright 1989-2017 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 
29 /**
30  * Pass: COPY_VALUE_OF_WRITE
31  * Debug mode: MPI_GENERATION_DEBUG_LEVEL
32  * Properties used:
33  * - MPI_NBR_CLUSTER
34  * - MPI_DUPLICATE_VARIABLE_PREFIX
35  * Resource needed:
36  * - DBR_PROPER_EFFECTS
37  * - DBR_CUMULATED_EFFECTS
38  * - DBR_TASK
39  **
40  * Pass: COPY_VALUE_OF_WRITE_WITH_CUMULATED_REGIONS
41  * Debug mode: MPI_GENERATION_DEBUG_LEVEL
42  * Properties used:
43  * - MPI_NBR_CLUSTER
44  * - MPI_DUPLICATE_VARIABLE_PREFIX
45  * Resource needed:
46  * - DBR_PROPER_EFFECTS
47  * - DBR_CUMULATED_EFFECTS
48  * - DBR_LIVE_OUT_REGIONS
49  * - DBR_TASK
50  *
51  */
52 
53 #include <stdlib.h>
54 #include <stdio.h>
55 
56 #include "genC.h"
57 #include "linear.h"
58 
59 #include "resources.h"
60 #include "database.h"
61 #include "ri.h"
62 #include "ri-util.h"
63 #include "effects.h"
64 #include "effects-util.h"
65 #include "pipsdbm.h"
66 
67 #include "effects-generic.h"
68 #include "effects-simple.h"
69 #include "effects-convex.h" //for debug prettyprint
70 #include "control.h"
71 
72 #include "misc.h"
73 
74 #include "properties.h"
75 
76 #include "conversion.h"
77 
78 #include "task_parallelization.h"
79 #include "prettyprint.h"
80 #include "workspace-util.h"
81 /**
82  *
83  */
86 }
87 
88 /*******************************************************
89  * UTILITIES : BEGIN *
90  *******************************************************/
91 /**
92  * Maybe these function can be move in statement.c?
93  */
94 /**
95  * statement_convert_to_statement_with_sequence_of_intruction
96  * transform a statement s to a statement of sequence
97  * Maybe can be move to statement.C but need to add some tests in that case
98  * inspired by generic_insert_statement
99  * \param s statement to convert into a sequence
100  * modify s by side effect
101  * \param extensions_on_sequence determine where the extension have to be place
102  * if true, the extension is for the sequence statement
103  * if false, the extension is for the statement inside the sequence
104  */
105 static void statement_convert_to_statement_with_sequence_of_intruction (statement s, bool extensions_on_sequence) {
106  ifdebug(4) {
107  pips_debug(4, "begin\n");
108  pips_debug(4, "statement to put into a block : \n");
109  print_statement(s);
110  }
111 
112  // s2 will be the statement inside the sequence
113  // it herite label, number, ordering, comment, declarations and instructions
114  // it doesn't have extensions or synchronization
116  statement_label(s),
117  statement_number(s),
123  extensions_on_sequence?empty_extensions():statement_extensions(s),
125  );
126  pips_assert("statement s2 is consistent", statement_consistent_p(s2));
127 
128  // no duplication
129  // The sequence statement lost label, number, ordering, comment, declarations
130  // But keep extensions and synchronization
137  statement_decls_text(s)=NULL;
138  if (!extensions_on_sequence)
140  //statement_synchronization(s) = make_synchronization_none();
141 
143  pips_assert("statement s is consistent", statement_consistent_p(s));
144 
145  /*
146  * other possible version for this function
147  * BUT statement s can change/isn't modify all the time by side effect
148  * so we have to return the value of a possible new statement
149  * and sometime not a new statement
150  * so not all the time homogeneous in the computation :(
151  * remark: if we use this version also have to modify copy_n_reference to make a return statement
152  s = make_block_with_stmt_if_not_already(s);
153  if (extensions_on_sequence) {
154  extensions_non_recursive_free(statement_extensions(s));
155  statement_extensions(s) = statement_extensions(STATEMENT(CAR(sequence_statements(instruction_sequence(statement_instruction(s))))));
156  statement_extensions(STATEMENT(CAR(sequence_statements(instruction_sequence(statement_instruction(s)))))) = empty_extensions();
157  }
158  pips_assert("statement s is consistent", statement_consistent_p(s));
159  return s;
160  */
161 
162  ifdebug(4) {
163  pips_debug(4, "statement after put into a block : \n");
164  print_statement(s);
165  pips_debug(4, "end\n");
166  }
167 }
168 
169 
170 /**
171  * statement_with_side_effect_p
172  * Check if the statement make side effect in a variable
173  * a side effect for a statement is defined by doing a read and
174  * a write on the same variable for the statement
175  *
176  * Maybe can be move to statement.c
177  * \param s statement to check the presence of modification by side effect
178  * \return true if the statement modify a variable by side effect
179  */
181  list lceffects = load_cumulated_rw_effects_list(s);
182  list lreffects = effects_read_effects(lceffects);
183  list lweffects = effects_write_effects(lceffects);
184 
185  FOREACH(EFFECT, we, lweffects) {
186  FOREACH(EFFECT, re, lreffects) {
188  return true;
189  }
190  }
191  }
192  return false;
193 }
194 
195 
196 
197 //void sc_extract_sc_on_vars(Psysteme sc, Pbase b, Psysteme *pwith, Psysteme *pwithout) {
198 // int nbvar0 = 0, nbvar = sc->dimension;
199 // while (nbvar - nbvar0) {
200 // sc_separate_on_vars(sc, b, pwith, pwithout);
201 // nbvar0 = nbvar;
202 // nbvar = (*pwith)->dimension;
203 // b = (*pwith)->base;
204 // }
205 // ifdebug(5) {
206 // printf("System WITH the variables \n");
207 // sc_print(*pwith, (get_variable_name_t) pips_region_user_name);
208 // printf("Nb_eq %d , Nb_ineq %d, dimension %d\n", (*pwith)->nb_eq, (*pwith)->nb_ineq, (*pwith)->dimension);
209 // printf("System WITHOUT the variables \n");
210 // sc_print(*pwithout, (get_variable_name_t) pips_region_user_name);
211 // printf("Nb_eq %d , Nb_ineq %d, dimension %d\n", (*pwithout)->nb_eq, (*pwithout)->nb_ineq, (*pwithout)->dimension);
212 // }
213 //}
214 
215 /*******************************************************
216  * UTILITIES : END *
217  *******************************************************/
218 
219 
220 /**
221  * translate an entity region in a variable entity if it's need
222  * if ent is an entity region return a variable entity
223  * else ent is already a variable entity so just return ent
224  * \param ent possible entity region
225  * \return an entity variable
226  */
228  //TODO It will probably be better the have a mapping especially for the constant
229  //string prefix = "__index_region_for_copy";
230  string scope = strdup(concatenate("0", BLOCK_SEP_STRING, NULL));
231  const char * prefix = get_string_property((const char *) MPI_GENERATION_PREFIX);
232  string new_name = strdup(concatenate(scope, prefix, "_index_", entity_local_name(ent), "_", i2a(taskid), "_", NULL));
233 
234  const char * mod_name = get_current_module_name();
235  if (variable_phi_p(ent)) {
236  return find_or_create_scalar_entity(new_name, mod_name, is_basic_int);
237  }
238  if (variable_psi_p(ent)) {
239  //really need?
240  return find_or_create_scalar_entity(new_name, mod_name, is_basic_int);
241  }
242  if (variable_beta_p(ent)) {
243  //really need?
244  return find_or_create_scalar_entity(new_name, mod_name, is_basic_int);
245  }
246  if (variable_rho_p(ent)) {
247  //really need?
248  return find_or_create_scalar_entity(new_name, mod_name, is_basic_int);
249  }
250  free(new_name);
251  return ent;
252 }
253 
254 /**
255  * call with gen_recurse
256  * modify by side effect the variable of the reference to be sure to be a variable entity
257  * and not a region entity in some cases
258  * \param ref reference to treat
259  */
260 static void translate_reference_region(reference ref, int * taskid) {
263 }
264 
265 /**
266  * make_statement_copy_i
267  * generate a copy_statement
268  * with ref, generate a statement:
269  * ref_i = ref;
270  * \param ref reference lhs/rhs
271  * \param i cluster number for the lhs of the statement generate
272  * \return statement: "ref_i = ref;"
273  */
274 static statement make_statement_copy_i (reference ref, int i, int taskid) {
276 
278  reference rhsref = copy_reference(ref);
281  entity lhsent = entity_undefined;
282  string name = "";
283  const char * prefix = get_string_property((const char *) MPI_GENERATION_PREFIX);
284 
285  // name: name of the entity variable for cluster number i
286  name = concatenate(
289  prefix, entity_user_name(var), "_", i2a(i),
290  NULL);
291 
292  pips_debug(5, "entity name to find : %s \n", name);
293 
294  //search the entity on proc i corresponded to the entity var to copy
295  if ((lhsent = gen_find_tabulated(name, entity_domain)) != entity_undefined) {
296  //lhsref = make_reference(lhsent, index_copy_with_translation_of_region(reference_indices(ref)));
300  statement_comments(scopy) = strdup("distributed send/receive");
301  pips_assert("statement scopy is consistent", statement_consistent_p(scopy));
302  }
303  //TODO this is a workaround for global variable
304  else if (true) {
305  //TOP-LEVEL
306  pips_user_warning("entity_module_name(var)=%s", entity_module_name(var));
307  scopy = make_nop_statement();
308  //scopy = make_continue_statement(entity_undefined);
309  }
310  else {
311  pips_internal_error("The variable with name %s doesn't exist.\n"
312  " PIPS can't generate the copy for this variable.\n"
313  " Try to launch pass VARIABLE_REPLICATION.\n", name);
314  }
315  ifdebug(5) {
316  pips_debug(5, "copy_statement generated:\n");
317  print_statement(scopy);
318  }
319  return scopy;
320 }
321 
322 /**
323  * copy_n_statement
324  * generate and add nbr statements of copy
325  * with reference ref, we have the variable that has a write effect and
326  * make some copy for the variables on the other proc
327  * example:
328  * lhs = rhs;
329  * ------->
330  * lhs_0 = rhs;
331  * lhs_1 = rhs;
332  * ...
333  * \param nbr number of copy wanted (number of proc asked)
334  * \param st statement after which we make the copy/ statement which has a write effect
335  */
336 static void copy_n_statement(list lweffects, int nbr, statement st) {
337  pips_assert("statement st is consistent", statement_consistent_p(st));
338  ifdebug(2) {
339  pips_debug(2, "begin\n");
340  pips_debug(2, "statement with : \n");
341  print_statement(st);
342  }
343 
345 
347  pips_user_warning("statement %s, have side effect.\n"
348  "The result of the generated code can be wrong without no other pass transformation.\n"
349  "Need to execute ELIMINATE_ORIGINAL_VARIABLE\n", statement_identification(st));
350  }
351 
352  list lstatement = NIL;
353 
354  for (int i=0; i<nbr; i++) {
355  statement sti;
356  task new_task = make_task(
357  task_id(t),
359  i,
361  );
362 
363  sti = copy_statement(st);
365  ifdebug(3) {
366  print_statement(sti);
367  }
368 
369  if (//statement_with_pragma_p(sti) && //because of the mapping of the resource have to always doing it to update mapping of statement
372  pips_assert("statement sti is consistent", statement_consistent_p(sti));
374  }
376  FOREACH(EFFECT, we, lweffects) {
377  reference wref = effect_any_reference(we);
378  entity went = reference_variable(wref);
379  if(!effects_package_entity_p(went)
380  && !ENTITY_STDERR_P(went) && !ENTITY_STDIN_P(went) && !ENTITY_STDOUT_P(went)) {
381  scopy = make_statement_copy_i(wref, i, task_id(t));
382  pips_assert("statement scopy is consistent", statement_consistent_p(scopy));
383  store_or_update_parallel_task_mapping(scopy, new_task);
384 
385  insert_statement(sti, scopy, false);
386  pips_assert("statement sti is consistent", statement_consistent_p(sti));
387  scopy = statement_undefined;
388  }
389  }
390  lstatement = CONS(STATEMENT, sti, lstatement);
391  }
392 
393  if (!ENDP(lstatement)) {
400  statement_decls_text(st)=NULL;
402  //statement_synchronization(s) = make_synchronization_none();
403 
405  }
406  else {
407  pips_internal_error("Normally never appear.");
408  }
409 
410  ifdebug(2) {
411  pips_debug(2, "statement with : \n");
412  print_statement(st);
413  pips_debug(2, "end\n");
414  }
415 }
416 
417 /**
418  * copy_n_reference
419  * generate and add nbr statements of copy
420  * with reference ref, we have the variable that has a write effect and
421  * make some copy for the variables on the other proc
422  * example:
423  * lhs = rhs;
424  * -------> lhs = rhs;
425  * lhs_0 = lhs;
426  * lhs_1 = lhs;
427  * ...
428  * \param ref reference of the variable written
429  * \param nbr number of copy wanted (number of proc asked)
430  * \param st statement after which we make the copy/ statement which has a write effect
431  */
432 static void copy_n_reference(reference ref, int nbr, statement st) {
433  pips_assert("statement st is consistent", statement_consistent_p(st));
434  //entity var = reference_variable(ref);
437  ifdebug(2) {
438  pips_debug(2, "begin\n");
439  pips_debug(2, "statement with : \n");
440  print_statement(st);
441  }
442 
443  if (indices != NIL) {
444  FOREACH(EXPRESSION, index, indices) {
445  if (expression_with_side_effect_p(index)) {
446  /* TODO tester si side effect dans les subscripte
447  * si oui renvoyer erreur
448  * faire pass pour extraire side-effect des subscript si possible
449  * existe déjà?
450  */
451  pips_user_warning("presence of side effect in subscript expression %p : %s\n"
452  "Result of this pass can be false\n", index, expression_to_string(index));
453  }
454  }
455  }
456 
457  // if the statement st have a pragma and it's not a block
458  // we convert st to a block statement
459  // if we don't make the convertion, the copy statement won't be affect by the pragma
460  // another possible solution is to add the pragma for the copy statement
461  if (//statement_with_pragma_p(st) && //because of the mapping of the resource have to always doing it to update mapping of statement
464  pips_assert("statement st is consistent", statement_consistent_p(st));
466  }
467 
469 
470  //Make copy for each cluster
471  for (int i=0; i<nbr; i++) {
472  scopy = make_statement_copy_i(ref, i, task_id(t));
473  pips_assert("statement scopy is consistent", statement_consistent_p(scopy));
475 
476  insert_statement(st, scopy, false);
477  pips_assert("statement st is consistent", statement_consistent_p(st));
478 
479  scopy = statement_undefined;
480  }
481 
482  ifdebug(5) {
483  pips_debug(5, "statement with : \n");
484  print_statement(st);
485  pips_debug(5, "end\n");
486  }
487 }
488 
489 /**
490  * copy_write_statement
491  * for the statement s, check if there is/are write effect
492  * foreach write effect make a copy statement for the variable written on there equivalent for each cluster.
493  * \param s statement to check if it's need to make copy
494  */
496  pips_debug(3, "begin\n");
497  if (!declaration_statement_p(s)) {
498  list lpeffects = NIL;
499  list lweffects = NIL;
502 
503  lpeffects = load_proper_rw_effects_list(s);
504  lweffects = effects_write_effects(lpeffects);
505 
506  if (!ENDP(lweffects)) {
507  //There is some write
508  if (task_on_cluster(t) == -1) {
509  //The statement must be executed by all the clusters
510  // copy the same statement
511  // lhs=rhs; -> lhs=rhs; lhs_1=rhs; ...
512  //TODO
513  // print_statement(s);
514  copy_n_statement(lweffects, nbr_copy, s);
515  }
516  else {
517  //The statement is executed by 1 cluster
518  //for each write effect, we make nbr_copy copy statement of the reference of the write effect
519  FOREACH(EFFECT, we, lweffects)
520  {
521  reference wref = effect_any_reference(we);
522  entity went = reference_variable(wref);
523  // test if the entity decl is not in the private list of the task, if so no copy
524  if (!entity_in_list_p(went, task_private_data(t))) {
525  // copy the value of the lhs
526  // lhs=rhs; -> lhs=rhs; lhs_1=lhs; ...
527  if(!effects_package_entity_p(went)
528  && !ENTITY_STDERR_P(went) && !ENTITY_STDIN_P(went) && !ENTITY_STDOUT_P(went))
529  //don't want, rand, malloc, printf, scanf...
530  copy_n_reference(wref, nbr_copy, s);
531  }
532  }
533  }
534  }
535  }
536  pips_debug(3, "end\n");
537 }
538 
539 /**
540  * PIPS pass
541  */
542 bool copy_value_of_write(const char* module_name) {
544  bool good_result_p = true;
545 
546  debug_on("MPI_GENERATION_DEBUG_LEVEL");
547  pips_debug(1, "begin\n");
548 
549  //-- configure environment --//
551 
553  db_get_memory_resource(DBR_CODE, module_name, true) );
555 
556  pips_assert("Statement should be OK before...",
558 
560 
561  //-- get dependencies --//
562 // if(use_points_to) {
563 // set_pointer_info_kind(with_points_to); //enough?
564 // }
566  db_get_memory_resource(DBR_PROPER_EFFECTS, module_name, true));
568  db_get_memory_resource(DBR_CUMULATED_EFFECTS, module_name, true));
570  db_get_memory_resource(DBR_TASK, module_name, true));
571 
572 
573  //-- Make the job -- //
575 // gen_recurse(module_statement, statement_domain, copy_write_statement, gen_true);
576 // if(use_points_to) {
577 // //TODO
578 // //gen_recurse(module_statement, statement_domain, gen_true, identity_statement_remove_with_points_to);
579 // }
580 
581  pips_assert("Statement should be OK after...",
583 
584  // Removed useless block created by the insert_statement
586 
587  /* Reorder the module, because some statements have been added.
588  Well, the order on the remaining statements should be the same,
589  but by reordering the statements, the number are consecutive. Just
590  for pretty print... :-) */
592 
593  pips_assert("Statement should be OK after...",
595 
596  //-- Save modified code to database --//
599 
606 
607  pips_debug(1, "end\n");
608  debug_off();
609 
610  return (good_result_p);
611 }
612 
613 /*********************************************
614  * With cumulated regions
615  *********************************************/
616 
617 /**
618  * copy_write_statement_with_cumulated_regions
619  * foreach first level statement in module_statement
620  * generate copies for variables present in out-region
621  * if it's an array region, generate variable for indices
622  * \param module_statement a module statement to work on
623  * modification of module_statement by side effect
624  */
626  ifdebug(2) {
627  pips_debug(2, "begin\n");
628  pips_debug(2, "statement with : \n");
630  }
631 
633  list loutregioneffects = NIL;
634  list lweffects = NIL;
635  task t = task_undefined;
638  list stats = sequence_statements(seq);
639 
640  FOREACH(STATEMENT, s, stats) {
641  loutregioneffects = load_live_out_regions_list(s);
642  //loutregioneffects = load_statement_out_regions(s);
643  //really need? since we use out_regions, all the list of effect must already be write.
644  lweffects = effects_write_effects(loutregioneffects);
646 
647  if (!ENDP(lweffects)) {
648  //There is some write
649  if (task_on_cluster(t) == -1) {
650  //The statement must be executed by all the clusters
651  // copy the same statement
652  // lhs=rhs; -> lhs=rhs; lhs_1=rhs; ...
653  copy_n_statement(lweffects, nbr_copy, s);
654  //TODO boucle for min/max à rajouter pour les tableaux
655  }
656  else {
657  //The statement is executed by 1 cluster
658  //for each write effect, we make nbr_copy copy statement of the reference of the write effect
659  FOREACH(EFFECT, we, lweffects) {
660  reference wref = effect_any_reference(we);
661  entity went = reference_variable(wref);
662 
663  /* test if the entity went is not in the private list of the task,
664  * don't want rand, malloc, printf, scanf...
665  * if so no copy
666  */
667  if (!entity_in_list_p(went, task_private_data(t)) &&
668  !effects_package_entity_p(went) &&
669  !ENTITY_STDERR_P(went) && !ENTITY_STDIN_P(went) && !ENTITY_STDOUT_P(went)
670  ) {
671  // copy the value of the lhs
672  // lhs=rhs; -> lhs=rhs; lhs_1=lhs; ...
673 
674  ifdebug(2) {
675  pips_debug(2, "write effect on variable:\n");
676  print_entity_variable(went);
677  pips_debug(2, "system of constraints:\n");
678  print_region_sc(we);
679  }
680 
681  descriptor desceffect = effect_descriptor(we);
683 
684  //not a write region but still write effect (eg x=0;)
685  if (descriptor_none_p(desceffect) || indices == NIL) {
686  copy_n_reference(wref, nbr_copy, s);
687  }
688  //write region (eg a[i]=i; with 0<i<10)
689  else if (descriptor_convex_p(desceffect)) {
690  Psysteme sc = descriptor_convex(desceffect);
691  statement sequence_statement_for_copy = make_empty_block_statement();
692  store_or_update_parallel_task_mapping(sequence_statement_for_copy, t);
693  //statement sequence_statement_for_copy = make_block_statement(CONS(STATEMENT, make_plain_continue_statement(), NIL));
694 
695  Psysteme sc2 = sc_dup(sc);
696  Pbase base_index = NULL;
697  FOREACH(EXPRESSION, index, indices) {
698  entity indexent = expression_to_entity(index);
700 
701  sc2 = sc_variable_rename(sc2, (Variable) indexent, (Variable) nent);
702  base_index = base_add_variable(base_index, (Variable) nent);
703  }
704  //base_index = base_reversal(base_index);
705 
706  Psysteme condition = SC_UNDEFINED,
707  enumeration = SC_UNDEFINED;
708 
709  algorithm_row_echelon(sc2, base_index,
710  &condition, &enumeration);
711 
712  ifdebug(8) {
713  pips_debug(8, "sc:\n");
714  if (sc2!=NULL){
716  pips_debug(8, "Nb_eq %d , Nb_ineq %d, dimension %d\n", (sc2)->nb_eq, (sc2)->nb_ineq, (sc2)->dimension);
717  }
718  else
719  pips_debug(8, "sc2==NULL\n");
720 
721  pips_debug(8, "condition:\n");
722  if (condition!=NULL){
724  pips_debug(8, "Nb_eq %d , Nb_ineq %d, dimension %d\n", (condition)->nb_eq, (condition)->nb_ineq, (condition)->dimension);
725  }
726  else
727  pips_debug(8, "condition==NULL\n");
728 
729  pips_debug(8, "enumeration:\n");
730  if (enumeration!=NULL) {
732  pips_debug(8, "Nb_eq %d , Nb_ineq %d, dimension %d\n", (enumeration)->nb_eq, (enumeration)->nb_ineq, (enumeration)->dimension);
733  }
734  else
735  pips_debug(8, "enumeration==NULL\n");
736  }
737 
738  statement stat;
739  stat = systeme_to_loop_nest(enumeration, base_to_list(base_index),
740  sequence_statement_for_copy,
743 
744  //add the declarations if necessary
746  BASE_FOREACH(var, base_index) {
747  entity ne = (entity) var;
748 
749  //if entity ne not declare, add the declaration
751  add_declaration_statement(stat, ne);
752  //add_declaration_statement_at_beginning(stat, ne);
755  //ram r = storage_ram(entity_storage(ne));
756  //entity m = ram_function(r);
757  //AddEntityToDeclarations(ne, m);
758  }
759  }
761 
762  //fill the body of the loop
763  //generate the copy lhs0[i0] = lhs[i0]
764  copy_n_reference(wref, nbr_copy, sequence_statement_for_copy);
765 
766  //add the copy array statements (the loop) to the program
767  if (!statement_sequence_p(s)) {
769  //statement_convert_to_statement_with_sequence_of_intruction(s, false);
770  //store_or_update_parallel_task_mapping(STATEMENT(CAR(sequence_statements(instruction_sequence(statement_instruction(s))))), t);
771  }
772  insert_comments_to_statement(stat, "Copy statements generated with OUT-REGION");
773  insert_statement(s, stat, false);
774  }
775  else if (descriptor_convexunion_p(desceffect)) {
776  //TODO
777  pips_internal_error("Not done yet...\n");
778  }
779  else {
780  pips_internal_error("This case never occurs\n descriptor = %d\n", descriptor_tag(desceffect));
781  }
782  }
783  }
784  }
785  }
786 
787  loutregioneffects = NIL;
788  lweffects = NIL;
789  t = task_undefined;
790  }
791  }
792  else {
793  pips_internal_error("The statement must be the module statement (a sequence of instruction).\n");
794  }
795 
796  ifdebug(2) {
797  pips_debug(2, "statement with : \n");
799  pips_debug(2, "end\n");
800  }
801 }
802 
803 /**
804  * PIPS pass
805  */
808  bool good_result_p = true;
809 
810  debug_on("MPI_GENERATION_DEBUG_LEVEL");
811  pips_debug(1, "begin\n");
812 
813  //-- configure environment --//
815 
817  db_get_memory_resource(DBR_CODE, module_name, true) );
819 
820  pips_assert("Statement should be OK before...",
822 
824 
825  //-- get dependencies --//
826 // if(use_points_to) {
827 // set_pointer_info_kind(with_points_to); //enough?
828 // }
830  db_get_memory_resource(DBR_PROPER_EFFECTS, module_name, true));
832  db_get_memory_resource(DBR_CUMULATED_EFFECTS, module_name, true));
834  //set_out_effects((statement_effects)
835  db_get_memory_resource(DBR_LIVE_OUT_REGIONS, module_name, true));
837  db_get_memory_resource(DBR_TASK, module_name, true));
838 
839 
840  //-- Make the job -- //
841  //No gen_recurse, only want to work on statement on the first level of the function
843 // gen_recurse(module_statement, statement_domain, gen_true, copy_write_statement_with_cumulated_regions);
844 // if(use_points_to) {
845 // //TODO
846 // //gen_recurse(module_statement, statement_domain, gen_true, copy_write_statement_with_cumulated_regions);
847 // }
848 
849  pips_assert("Statement should be OK after...",
851 
852  // Removed useless block created by the insert_statement
854 
855  /* Reorder the module, because some statements have been added.
856  Well, the order on the remaining statements should be the same,
857  but by reordering the statements, the number are consecutive. Just
858  for pretty print... :-) */
860 
861  pips_assert("Statement should be OK after...",
863 
864  //-- Save modified code to database --//
866 
874 
875  pips_debug(1, "end\n");
876  debug_off();
877 
878  return (good_result_p);
879 }
880 
881 
882 
883 
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
int get_int_property(const string)
statement copy_statement(statement p)
STATEMENT.
Definition: ri.c:2186
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
bool statement_consistent_p(statement p)
Definition: ri.c:2195
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
instruction make_instruction_sequence(sequence _field_)
Definition: ri.c:1169
reference copy_reference(reference p)
REFERENCE.
Definition: ri.c:2047
synchronization make_synchronization_none(void)
Definition: ri.c:2424
sequence make_sequence(list a)
Definition: ri.c:2125
task make_task(intptr_t a1, list a2, intptr_t a3, bool a4)
Definition: task_private.c:109
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
static statement module_statement
Definition: alias_check.c:125
Pbase base_add_variable(Pbase b, Variable var)
Pbase base_add_variable(Pbase b, Variable v): add variable v as a new dimension to basis b at the end...
Definition: base.c:88
void unspaghettify_statement(statement)
The real entry point of unspaghettify:
statement systeme_to_loop_nest(Psysteme, list, statement, entity)
sc is used to generate the loop nest bounds for variables vars.
bool copy_value_of_write(const char *module_name)
PIPS pass.
static void translate_reference_region(reference ref, int *taskid)
call with gen_recurse modify by side effect the variable of the reference to be sure to be a variable...
bool copy_value_of_write_with_cumulated_regions(const char *module_name)
PIPS pass.
static entity region_entity_variable_to_new_declare_entity(entity ent, int taskid)
translate an entity region in a variable entity if it's need if ent is an entity region return a vari...
static statement make_statement_copy_i(reference ref, int i, int taskid)
make_statement_copy_i generate a copy_statement with ref, generate a statement: ref_i = ref;
static void statement_convert_to_statement_with_sequence_of_intruction(statement s, bool extensions_on_sequence)
Maybe these function can be move in statement.c?
static void copy_n_reference(reference ref, int nbr, statement st)
copy_n_reference generate and add nbr statements of copy with reference ref, we have the variable tha...
static string copy_variable_declaration_commenter(__attribute__((unused)) entity e)
Pass: COPY_VALUE_OF_WRITE Debug mode: MPI_GENERATION_DEBUG_LEVEL Properties used:
static bool statement_with_side_effect_p(statement s)
statement_with_side_effect_p Check if the statement make side effect in a variable a side effect for ...
static void copy_write_statement(statement s)
copy_write_statement for the statement s, check if there is/are write effect foreach write effect mak...
static void copy_write_statement_with_cumulated_regions(statement module_statement)
copy_write_statement_with_cumulated_regions foreach first level statement in module_statement generat...
static void copy_n_statement(list lweffects, int nbr, statement st)
copy_n_statement generate and add nbr statements of copy with reference ref, we have the variable tha...
void print_region_sc(effect)
void reset_live_out_regions(void)
void set_live_out_regions(statement_effects)
list effects_read_effects(list)
list load_proper_rw_effects_list(statement)
void reset_proper_rw_effects(void)
void set_proper_rw_effects(statement_effects)
void set_cumulated_rw_effects(statement_effects)
list load_cumulated_rw_effects_list(statement)
list effects_write_effects(list)
void reset_cumulated_rw_effects(void)
list load_live_out_regions_list(statement)
bool expression_with_side_effect_p(expression)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define variable_beta_p(e)
#define variable_rho_p(e)
#define variable_psi_p(e)
#define variable_phi_p(e)
true if e is a phi variable PHI entities have a name like: REGIONS:PHI#, where # is a number.
const char * pips_region_user_name(entity)
char * pips_region_user_name(entity ent) output : the name of entity.
Definition: prettyprint.c:169
#define descriptor_tag(x)
Definition: effects.h:595
#define descriptor_convex_p(x)
Definition: effects.h:599
#define effect_descriptor(x)
Definition: effects.h:646
#define descriptor_convexunion_p(x)
Definition: effects.h:596
#define descriptor_convex(x)
Definition: effects.h:601
#define descriptor_none_p(x)
Definition: effects.h:602
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
#define effect_cell(x)
Definition: effects.h:640
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 gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
void free(void *)
bool cells_may_conflict_p(cell c1, cell c2)
Check if two cell may conflict.
Definition: conflicts.c:696
statement make_empty_block_statement(void)
Build an empty statement (block/sequence)
Definition: statement.c:625
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
const char * get_current_module_name(void)
Get the name of the current module.
Definition: static.c:121
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
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#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
#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
list gen_full_copy_list(list l)
Copy a list structure with element copy.
Definition: list.c:535
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 statement_sequence_p(statement)
Statement classes induced from instruction type.
Definition: statement.c:335
statement make_assign_statement(expression, expression)
Definition: statement.c:583
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
string statement_identification(statement)
Like external_statement_identification(), but with internal information, the hexadecimal address of t...
Definition: statement.c:1700
void pop_generated_variable_commenter(void)
Definition: statement.c:2623
list statement_to_direct_declarations(statement)
Returns the declarations contained directly in a statement s.
Definition: statement.c:3366
void insert_statement(statement, statement, bool)
This is the normal entry point.
Definition: statement.c:2570
statement add_declaration_statement(statement, entity)
Definition: statement.c:2790
void push_generated_variable_commenter(string(*)(entity))
Definition: statement.c:2616
bool declaration_statement_p(statement)
Had to be optimized according to Beatrice Creusillet.
Definition: statement.c:224
list base_to_list(Pbase base)
Most includes are centralized here.
static list indices
Definition: icm.c:204
#define debug_on(env)
Definition: misc-local.h:157
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_user_warning
Definition: misc-local.h:146
#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 debug_off()
Definition: misc-local.h:160
#define MODULE_SEP_STRING
Definition: naming-local.h:30
#define BLOCK_SEP_STRING
Scope separator.
Definition: naming-local.h:50
#define STATEMENT_ORDERING_UNDEFINED
mapping.h inclusion
Definition: newgen-local.h:35
char * i2a(int)
I2A (Integer TO Ascii) yields a string for a given Integer.
Definition: string.c:121
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
void * gen_find_tabulated(const char *, int)
Definition: tabulated.c:218
#define string_undefined
Definition: newgen_types.h:40
hash_table set_ordering_to_statement(statement s)
To be used instead of initialize_ordering_to_statement() to make sure that the hash table ots is in s...
Definition: ordering.c:172
void reset_ordering_to_statement(void)
Reset the mapping from ordering to statement.
Definition: ordering.c:185
void print_entity_variable(entity e)
print_entity_variable(e)
Definition: entity.c:56
string expression_to_string(expression e)
Definition: expression.c:77
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
static const char * prefix
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
#define make_nop_statement
An alias for make_empty_block_statement.
#define ENTITY_STDIN_P(e)
#define STATEMENT_NUMBER_UNDEFINED
default values
#define DIVIDE_OPERATOR_NAME
#define ENTITY_STDERR_P(e)
#define ENTITY_STDOUT_P(e)
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
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
bool entity_in_list_p(entity ent, list ent_l)
look for ent in ent_l
Definition: entity.c:2221
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
bool effects_package_entity_p(entity e)
checks if an entity is an IO_EFFECTS_PACKAGE_NAME, a MALLOC_EFFECTS_NAME or a RAND_EFFECTS_PACKAGE_NA...
Definition: entity.c:1181
entity entity_empty_label(void)
Definition: entity.c:1105
string local_name_to_scope(const char *ln)
allocates a new string
Definition: entity.c:563
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
expression reference_to_expression(reference r)
Definition: expression.c:196
entity expression_to_entity(expression e)
just returns the entity of an expression, or entity_undefined
Definition: expression.c:3140
extensions empty_extensions(void)
extension.c
Definition: extension.c:43
void AddLocalEntityToDeclarationsOnly(entity, entity, statement)
Add the variable entity e to the list of variables of the function module.
Definition: variable.c:253
entity find_or_create_scalar_entity(const char *, const char *, tag)
Looks for an entity which should be a scalar of the specified basic.
Definition: variable.c:1025
@ is_basic_int
Definition: ri.h:571
#define instruction_sequence_p(x)
Definition: ri.h:1512
#define reference_undefined
Definition: ri.h:2302
#define reference_variable(x)
Definition: ri.h:2326
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define statement_ordering(x)
Definition: ri.h:2454
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define instruction_undefined
Definition: ri.h:1454
#define statement_label(x)
Definition: ri.h:2450
#define reference_domain
newgen_range_domain_defined
Definition: ri.h:338
#define entity_undefined
Definition: ri.h:2761
#define sequence_statements(x)
Definition: ri.h:2360
#define reference_indices(x)
Definition: ri.h:2328
#define statement_extensions(x)
Definition: ri.h:2464
#define instruction_sequence(x)
Definition: ri.h:1514
#define statement_declarations(x)
Definition: ri.h:2460
#define statement_instruction(x)
Definition: ri.h:2458
#define statement_comments(x)
Definition: ri.h:2456
#define statement_decls_text(x)
Definition: ri.h:2462
#define statement_number(x)
Definition: ri.h:2452
#define entity_domain
newgen_syntax_domain_defined
Definition: ri.h:410
#define statement_undefined
Definition: ri.h:2419
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
Psysteme sc_variable_rename(Psysteme s, Variable v_old, Variable v_new)
Psysteme sc_variable_rename(Psysteme s, Variable v_old, Variable v_new): reecriture du systeme s remp...
Definition: sc.c:157
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
void sc_print(Psysteme ps, get_variable_name_t nom_var)
void sc_print()
Definition: sc_io.c:194
char * strdup()
void algorithm_row_echelon(Psysteme scn, Pbase base_index, Psysteme *pcondition, Psysteme *penumeration)
see comments above.
#define ifdebug(n)
Definition: sg.c:47
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 MPI_GENERATION_NBR_CLUSTER
#define COMMENT_COPY_VARIABLE
#define MPI_GENERATION_PREFIX
task load_parallel_task_mapping(statement)
void store_or_update_parallel_task_mapping(statement, task)
void set_parallel_task_mapping(statement_task)
void reset_parallel_task_mapping(void)
statement_task get_parallel_task_mapping(void)
#define task_synchronization(x)
Definition: task_private.h:121
#define task_id(x)
Definition: task_private.h:115
#define task_undefined
Definition: task_private.h:89
#define task_on_cluster(x)
Definition: task_private.h:119
#define task_private_data(x)
Definition: task_private.h:117
char *(* get_variable_name_t)(Variable)
Definition: vecteur-local.h:62
void * Variable
arithmetique is a requirement for vecteur, but I do not want to inforce it in all pips files....
Definition: vecteur-local.h:60
#define BASE_FOREACH(v, b)