PIPS
externalization.c
Go to the documentation of this file.
1 /*
2 
3  $Id: externalization.c 23495 2018-10-24 09:19:47Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 
28 #ifdef lint
29 static char vcid[] = "$Id: externalization.c 23495 2018-10-24 09:19:47Z coelho $";
30 #endif /* lint */
31 
32 
33 #include "safescale.h"
34 #include "workspace-util.h"
35 #include "text-util.h"
36 #include "syntheses.h"
37 #include "preprocessor.h"
38 
39 
40 /**
41  Adding in the statement containing comments in the list of statements
42  */
43 static void check_if_statement_contains_comment(statement s, void* a_context)
44 {
46  string comments;
47 
49  {
50  comments = strdup(statement_comments(s));
51 
52  if (strstr(comments, context->searched_string) != NULL)
53  {
54  context->list_of_statements = CONS(STATEMENT, s, context->list_of_statements);
55  }
56 
57  free(comments);
58  }
59 }
60 
61 
62 /**
63  Building a list with statements containing comments
64  */
65 static list get_statements_with_comments_containing(string comment_portion, statement stat)
66 {
67  string percent;
69 
70  /* Set searched string */
71  context.searched_string = strdup(comment_portion);
72  percent = strstr(context.searched_string, "%s");
73 
74  if (percent == NULL)
75  pips_user_error("Malformed statement comment to search. Should be of the form 'BLAH_%%s'\n");
76 
77  *percent = '\0';
78 
79  /* Reset and get list of statements */
80  context.list_of_statements = NIL;
81 
82  ifdebug(5) {
83  pips_debug(5, "Searching statements with comments: %s\n", context.searched_string);
84  pips_debug(5, "In statement:\n");
85  print_statement(stat);
86  }
87 
89 
90  free(context.searched_string);
91 
92  return context.list_of_statements;
93 }
94 
95 
96 /**
97  Return the identified function name of the externalized portion of code by searching comment matching tags EXTERNALIZED_CODE_PRAGMA_ANALYZED_TOP
98  Set the number of statements of this externalizable statement
99  */
100 static string get_externalized_and_analyzed_function_name(statement stat, int *stats_nb)
101 {
102  string comments;
103  string searched_string;
104  string comment_portion = strdup(EXTERNALIZED_CODE_PRAGMA_ANALYZED_TOP);
105  char *function_name = NULL;
106  char *next_line;
108 
109  pips_debug(7, "Statement to be processed: ");
110  print_statement(stat);
111 
113  {
115  }
116 
117  if (!statement_with_empty_comment_p(stat))
118  {
119  searched_string = strdup(comment_portion);
120  searched_string[strcspn(comment_portion, "%s")] = '\0';
121  comments = strdup(statement_comments(stat));
122  next_line = strtok(comments, "\n");
123 
124  if (next_line != NULL)
125  {
126  do
127  {
128  string first_occurence = strstr(next_line, searched_string);
129 
130  if (first_occurence != NULL)
131  {
132  function_name = malloc(256);
133  pips_debug(5, "Scanning: [%s] with [%s]", first_occurence, comment_portion);
134  sscanf (first_occurence, comment_portion, function_name, stats_nb);
135  pips_debug(5, "Found function: [%s] and %d stats \n", function_name, *stats_nb);
136  }
137 
138  next_line = strtok(NULL, "\n");
139  }
140  while (next_line != NULL);
141  }
142 
143  free(searched_string);
144  free(comments);
145  }
146 
147  free(comment_portion);
148 
149  return function_name;
150 }
151 
152 
153 /**
154  Get sequence containing a searched context
155  */
156 static void search_sequence_containing(statement s, void* a_context)
157 {
160 
162  {
163  MAP (STATEMENT, s2, {
164  if (s2 == context->searched_statement)
165  {
166  context->found_sequence_statement = s;
167  }
169  }
170 }
171 
172 
173 /**
174  Get statement containing a searched statement
175  */
176 static statement sequence_statement_containing(statement root_statement, statement searched_stat)
177 {
179 
180  context.searched_statement = searched_stat;
181  context.found_sequence_statement = NULL;
182 
184 
185  return context.found_sequence_statement;
186 }
187 
188 
189 /**
190  Compute union of exact regions
191  */
192 static list compute_regions_union(list l_in, list l_out)
193 {
194  list l_union = gen_copy_seq(l_in);
195 
196  pips_debug(4, "BEGIN of computing regions UNION\n");
197 
198  MAP(REGION, reg, {
199  entity e = region_entity(reg);
200  bool is_already_present = false;
201  region reg_already_present = NULL;
202 
203  MAP (REGION, union_reg, {
204  entity e2 = region_entity(union_reg);
205 
206  if (same_entity_p(e, e2))
207  {
208  is_already_present = true;
209  reg_already_present = union_reg;
210  }
211  }, l_union);
212 
213  if (is_already_present)
214  {
215  if (region_scalar_p(reg))
216  {
217  pips_debug(6, "Found SCALAR region already present [%s]. Ignored.\n", entity_local_name(e));
218  }
219  else
220  {
221  list new_regions;
222 
223  pips_debug(6, "Found ARRAY region already present [%s].\n", entity_local_name(e));
224  pips_debug(6, "Making UNION of:\n");
225 
226  print_region(reg);
227  pips_debug(6, "and:\n");
228  print_region(reg_already_present);
229  new_regions = region_must_union(reg,reg_already_present);
230 
231  pips_debug(6, "Getting:\n");
232 
233  print_regions(new_regions);
234 
235  if (gen_length(new_regions) > 1)
236  {
237  pips_internal_error("Regions union must refer to only ONE region !");
238  }
239  else
240  {
241  gen_remove(&l_union, reg_already_present);
242  l_union = CONS(REGION, REGION(gen_nth(0, new_regions)), l_union);
243  }
244  }
245  }
246  else
247  {
248  pips_debug(6, "Adding region for [%s]\n", entity_local_name(e));
249  l_union = CONS(REGION, reg, l_union);
250  }
251  }, l_out);
252 
253  pips_debug(4, "END of computing regions UNION\n");
254 
255  return l_union;
256 }
257 
258 
259 /**
260  Compute internal distribution context for statement externalized_code
261  */
262 static bool internal_compute_distribution_context(statement externalized_code, hash_table* ht_params, hash_table* ht_private, hash_table* ht_in_regions, hash_table* ht_out_regions, void* key_value)
263 {
264  bool returned_value = true;
265  list l_read, l_write, l_in, l_out;
266  list l_params = NIL;
267  list l_priv = NIL;
268 
269  pips_debug(6, "Compute regions\n");
270 
271  l_write = regions_dup(regions_write_regions(load_statement_local_regions(externalized_code)));
272  l_read = regions_dup(regions_read_regions(load_statement_local_regions(externalized_code)));
273  l_in = regions_dup(load_statement_in_regions(externalized_code));
274  l_out = regions_dup(load_statement_out_regions(externalized_code));
275 
276  ifdebug(6)
277  {
278  pips_debug(6, "READ regions: \n");
279  print_regions(l_read);
280  pips_debug(6, "WRITE regions: \n");
281  print_regions(l_write);
282  }
283 
284  l_params = compute_regions_union(l_in, l_out);
285  l_in = regions_dup(load_statement_in_regions(externalized_code));
286  l_out = regions_dup(load_statement_out_regions(externalized_code));
287  l_priv = RegionsEntitiesInfDifference(l_write, l_in, w_r_combinable_p);
288  l_priv = RegionsEntitiesInfDifference(l_priv, l_out, w_w_combinable_p);
289  l_in = regions_dup(load_statement_in_regions(externalized_code));
290  l_out = regions_dup(load_statement_out_regions(externalized_code));
291 
296 
297  ifdebug(2)
298  {
299  pips_debug(2, "IN regions: \n");
300  print_regions(l_in);
301  pips_debug(2, "OUT regions: \n");
302  print_regions(l_out);
303  pips_debug(2, "Params regions: \n");
304  print_regions(l_params);
305  pips_debug(2, "Private regions: \n");
306  print_regions(l_priv);
307  }
308 
309  /* Store results in hash_tables */
310  pips_debug(2, "Storing in hash_tables with key %s: \n", (string)key_value);
311  pips_debug(5, "Storing in ht_param: \n");
312 
313  if (!hash_defined_p(*ht_params, key_value))
314  {
315  hash_put(*ht_params, key_value, l_params);
316  }
317  else
318  {
319  pips_user_warning("Multiply defined value in PARAMS hash_table!\n");
320  returned_value = false;
321  }
322 
323  pips_debug(5, "Storing in ht_private: \n");
324 
325  if (!hash_defined_p(*ht_private, key_value))
326  {
327  hash_put(*ht_private, key_value, l_priv);
328  }
329  else
330  {
331  pips_user_warning("Multiply defined value in PRIVATE hash_table!\n");
332  returned_value = false;
333  }
334 
335  pips_debug(5, "Storing in ht_in_regions: \n");
336 
337  if (!hash_defined_p(*ht_in_regions, key_value))
338  {
339  hash_put(*ht_in_regions, key_value, l_in);
340  }
341  else
342  {
343  pips_user_warning("Multiply defined value in IN_REGIONS hash_table!\n");
344  returned_value = false;
345  }
346 
347  pips_debug(5, "Storing in ht_out_regions: \n");
348 
349  if (!hash_defined_p(*ht_out_regions, key_value))
350  {
351  hash_put(*ht_out_regions, key_value, l_out);
352  }
353  else
354  {
355  pips_user_warning("Multiply defined value in OUT_REGIONS hash_table!\n");
356  returned_value = false;
357  }
358 
359  return returned_value;
360 }
361 
362 
363 /**
364  Compute distribution context for statement externalized_code
365  */
366 static bool compute_distribution_context(list l_stats, statement module_stat, entity module, hash_table* ht_stats, hash_table* ht_params, hash_table* ht_private, hash_table* ht_in_regions, hash_table* ht_out_regions)
367 {
368  bool returned_value = true;
369 
370  pips_debug(5, "[BEGIN] compute_distribution_context for %s: \n", entity_local_name(module));
371 
372  /* Init hashtables */
373  *ht_stats = hash_table_make(hash_pointer, 0);
374  *ht_params = hash_table_make(hash_pointer, 0);
375  *ht_private = hash_table_make(hash_pointer, 0);
376  *ht_in_regions = hash_table_make(hash_pointer, 0);
377  *ht_out_regions = hash_table_make(hash_pointer, 0);
378 
379  MAP(STATEMENT, s, {
380  statement externalized_code = NULL;
381  int stats_nb;
382  string function_name = get_externalized_and_analyzed_function_name(s, &stats_nb);
383 
384  pips_debug(5, "Funtion name: %s\n", function_name);
385  pips_debug(5, "Number of statements: %d\n", stats_nb);
386 
387  if (stats_nb > 1)
388  {
389  externalized_code = sequence_statement_containing(module_stat, s);
390  }
391  else if (stats_nb == 1)
392  {
393  externalized_code = s;
394  }
395  else
396  {
397  pips_internal_error("Strange externalized code!");
398  }
399 
400  /* Register new externalized function */
401  pips_debug(5, "Register externalized function %s: \n", function_name);
402 
403  if (!hash_defined_p(*ht_stats, function_name))
404  {
405  hash_put(*ht_stats, function_name, externalized_code);
406  }
407  else
408  {
409  pips_user_warning("Multiply defined value in STATS hash_table!\n");
410  returned_value = false;
411  }
412 
413  pips_debug(3, "ANALYSING function named [%s]..................\n", function_name);
414 
415  if (!internal_compute_distribution_context(externalized_code, ht_params, ht_private, ht_in_regions, ht_out_regions, function_name))
416  {
417  returned_value = false;
418  }
419  }, l_stats);
420 
421  pips_debug(5, "[END] compute_distribution_context for %s: \n", entity_local_name(module));
422 
423  return returned_value;
424 }
425 
426 
427 /**
428  Create a variable declared as a parameter in specified module
429  */
430 static entity create_parameter_variable_for_new_module(entity a_variable, string new_name, string new_module_name, entity module, int param_nb)
431 {
433 
434  /* Test if entity exists and create it if not */
435  if ((gen_find_tabulated(concatenate(new_module_name, MODULE_SEP_STRING, new_name, NULL), entity_domain)) == entity_undefined)
436  {
438 
439  return new_variable;
440  }
441  else
442  {
443  pips_internal_error("Entity already exist: %s", new_name);
444 
445  return NULL;
446  }
447 }
448 
449 
450 /**
451  Create a private variable in specified module
452  */
453 static entity create_private_variable_for_new_module(entity a_variable, string new_name, string new_module_name, entity module)
454 {
456  entity a;
457  basic base;
458 
459  /* Test if entity exists and create it if not */
460  if ((gen_find_tabulated(concatenate(new_module_name, MODULE_SEP_STRING, new_name, NULL), entity_domain)) == entity_undefined)
461  {
463 
464  a = FindEntity(new_module_name, DYNAMIC_AREA_LOCAL_NAME);
467 
468  pips_debug(2, "Created new private variable: %s\n", entity_global_name(new_variable));
469 
470  return new_variable;
471  }
472  else
473  {
474  pips_internal_error("Entity already exist: %s", new_name);
475 
476  return NULL;
477  }
478 }
479 
480 
481 /**
482  Return EXTERNALIZED_FUNCTION_PARAM_NAME
483  */
485 {
486  char buffer[256];
487 
489 
490  return strdup(buffer);
491 }
492 
493 
494 /**
495  Return EXTERNALIZED_FUNCTION_PRIVATE_PARAM_NAME
496  */
498 {
499  char buffer[256];
500 
502 
503  return strdup(buffer);
504 }
505 
506 
507 
508 /**
509  Declare in the newly created module a new variable and replace all occurences to the old variable by the new created
510  */
511 static void add_parameter_variable_to_module(reference ref, entity module, statement stat, string new_module_name, int param_nb)
512 {
513  parameter new_parameter;
515  list module_parameters;
517  string variable_name;
518 
519  pips_debug(2, "Registering parameter: %s\n", entity_local_name(reference_variable(ref)));
520 
521  /* Assert that entity represent a value code */
522  pips_assert("It is a module", entity_module_p(module));
523 
524  /* Get the variable name */
526 
531 
532  new_parameter = make_parameter(entity_type(new_variable), make_mode(is_mode_reference, UU), make_dummy_unknown()); //FI: could be make_dummy_identifier(new_variable)
533  module_parameters = module_functional_parameters(module);
534  module_functional_parameters(module) = CONS(PARAMETER, new_parameter, module_parameters);
535 }
536 
537 
538 /**
539  Declare in the newly created module a new variable and replace all occurences to the old variable by the new created
540  */
541 static void add_private_variable_to_module(reference ref, entity module, statement stat, string new_module_name)
542 {
545  string variable_name;
546 
547  pips_debug(2, "Registering private variable: %s\n", entity_local_name(reference_variable(ref)));
548 
549  /* Assert that entity represent a value code */
550  pips_assert("It is a module", entity_module_p(module));
551 
552  /* Get the variable name */
554 
555  /* Creates the variable */
557 
561 
562 }
563 
564 
565 /**
566  Return a list of references corresponding to a list of regions
567  */
569 {
570  list l_ref = NIL;
571 
572  MAP(EFFECT, reg, {
574 
575  l_ref = CONS(REFERENCE, ref, l_ref);
577  pips_debug(4,"Entity: %s\n", entity_local_name(reference_variable(ref)));
578  }, l_regions);
579 
580  return l_ref;
581 }
582 
583 
584 /**
585  Dynamically build a new module with specified statement
586  */
587 static entity create_module_with_statement(statement stat, string new_module_name, list l_params, list l_priv)
588 {
589  entity new_module;
590  //string source_file;
591  //text text_code;
592  int param_nb = 0;
593 
594  pips_debug(5, "[BEGIN] create_module_with_statement\n");
595  pips_debug(2, "Creating new module: [%s]\n", new_module_name);
596 
598 
599  /* Deal with private variables */
600  MAP(REFERENCE, ref, {
601  add_private_variable_to_module(ref, new_module, stat, new_module_name);
602  }, references_for_regions(l_priv));
603 
604  /* Deal with parameter variables */
605  param_nb = gen_length(l_params);
606 
607  MAP(REFERENCE, ref, {
608  add_parameter_variable_to_module(ref, new_module, stat, new_module_name, param_nb);
609  param_nb--;
610  }, references_for_regions(l_params));
611 
612  pips_debug(2, "Making new module: [%s]\n", new_module_name);
613 
614  ifdebug(5)
615  {
616  pips_debug(5, "With statement: \n");
617  print_statement(stat);
618  }
619 
620  add_new_module(new_module_name, new_module, stat,
622 
623  pips_debug(5, "[END] create_module_with_statement\n");
624 
625  return new_module;
626 }
627 
628 
629 /**
630  Replace statement old_stat by statement new_stat and assert that this statement is contained in a sequence
631  */
632 static void replace_in_sequence_statement_with(statement old_stat, statement new_stat, statement root_stat)
633 {
634  statement sequence_statement = sequence_statement_containing(root_stat, old_stat);
635  list stats_list = sequence_statements(instruction_sequence(statement_instruction(sequence_statement)));
636  list new_stats_list = NIL;
637 
638  pips_debug(5, "BEGIN replace_in_sequence_statement_with:\n");
639  pips_assert("Statement is contained in a sequence", sequence_statement != NULL);
640 
641  MAP(STATEMENT, s, {
642  pips_debug(7, "Iterate on statement:\n");
643 
644  print_statement(s);
645 
646  if (s == old_stat)
647  {
648  pips_debug(7, "Replace this statement:\n");
649 
650  new_stats_list = CONS(STATEMENT, new_stat, new_stats_list);
651  }
652  else
653  {
654  pips_debug(7, "Keep this statement:\n");
655 
656  new_stats_list = CONS(STATEMENT, s, new_stats_list);
657  }
658  }, stats_list);
659 
660  sequence_statements(instruction_sequence(statement_instruction(sequence_statement))) = gen_nreverse(new_stats_list);
661 
662  ifdebug(7)
663  {
664  pips_debug(7, "I've got this for the sequence\n");
665  print_statement(sequence_statement);
666  pips_debug(7, "I've got this for the root statement\n");
667  print_statement(root_stat);
668  }
669 
670  pips_debug(5, "END replace_in_sequence_statement_with:\n");
671 }
672 
673 
674 /**
675  Externalize a specified code portion
676  */
677 static void distribute_code(string function_name, statement externalized_code, statement module_stat, list l_params, list l_priv)
678 {
679  entity new_module = create_module_with_statement(externalized_code, function_name, l_params, l_priv);
680  statement call_statement;
681  list call_params = NIL;
682  string call_comments;
683 
684  pips_debug(5, "[BEGIN] distribute_code\n");
685 
686  MAP(REFERENCE, ref, {
687  call_params = CONS(EXPRESSION, make_entity_expression(reference_variable(ref), NIL), call_params);
688  }, references_for_regions(l_params));
689 
690  /* Insert an analyzed tag */
691  {
692  char* new_tag = malloc(256);
693 
694  sprintf(new_tag, strdup(concatenate("\n! ", EXTERNALIZED_CODE_PRAGMA_CALL, "\n", NULL)), function_name);
695  call_comments = strdup(new_tag);
696  }
697 
698  call_statement = make_statement(entity_empty_label(),
699  statement_number(externalized_code),
700  statement_ordering(externalized_code),
701  call_comments,
703  make_call(new_module,
704  call_params)),
705  NIL,
706  NULL,
707  statement_extensions (externalized_code), make_synchronization_none());
708 
709  pips_debug(7, "BEFORE REPLACING\n");
710  pips_debug(7, "externalized_code=\n");
711  print_statement(externalized_code);
712  pips_debug(7, "call_statement=\n");
713  print_statement(call_statement);
714  pips_debug(7, "module_stat=\n");
715  print_statement(module_stat);
716 
717  replace_in_sequence_statement_with(externalized_code, call_statement, module_stat);
718 
719  pips_debug(7, "AFTER REPLACING\n");
720  pips_debug(7, "externalized_code=\n");
721  print_statement(externalized_code);
722  pips_debug(7, "call_statement=\n");
723  print_statement(call_statement);
724  pips_debug(7, "module_stat=\n");
725  print_statement(module_stat);
726 
727  pips_assert("Module structure is consistent after DISTRIBUTE_CODE", gen_consistent_p((gen_chunk*) new_module));
728  pips_assert("Statement structure is consistent after DISTRIBUTE_CODE", gen_consistent_p((gen_chunk*) externalized_code));
729  pips_assert("Statement is consistent after DISTRIBUTE_CODE", statement_consistent_p(externalized_code));
730 
731  pips_debug(7, "Code distribution for : [%s] is DONE\n", function_name);
732  pips_debug(5, "[END] distribute_code\n");
733 
734  free(call_comments);
735 }
736 
737 
738 /**
739  Distribute for main module module with root statement stat
740  */
741 static void distribute(statement module_stat, entity module)
742 {
744  hash_table ht_stats;
745  hash_table ht_params;
746  hash_table ht_private;
747  hash_table ht_in_regions;
748  hash_table ht_out_regions;
749 
750  pips_debug(5, "[BEGIN] distribute\n");
751  pips_debug(5, "Number of analyzed statements to distribute: %td\n", gen_length(l_stats));
752 
753  compute_distribution_context(l_stats, module_stat, module, &ht_stats, &ht_params, &ht_private, &ht_in_regions, &ht_out_regions);
754 
755  HASH_MAP(function_name, stat, {
756  distribute_code(function_name, stat, module_stat, hash_get(ht_params, function_name), hash_get(ht_private, function_name));
757  }, ht_stats);
758 
759  hash_table_free(ht_stats);
760  hash_table_free(ht_params);
761  hash_table_free(ht_private);
762  hash_table_free(ht_in_regions);
763  hash_table_free(ht_out_regions);
764 
765  pips_debug(5, "[END] distribute\n");
766 }
767 
768 
769 /**
770  Main phase for block code externalization
771  */
773 
775 {
776  statement module_stat;
777  entity module;
778 
779  /* Set and get the current properties concerning regions */
780  set_bool_property("MUST_REGIONS", true);
781  set_bool_property("EXACT_REGIONS", true);
783 
784  /* Get the resources */
785  module_stat = (statement) db_get_memory_resource(DBR_CODE, module_name, true);
787 
788  set_current_module_statement(module_stat);
790 
794 
795  /* Set dynamic_area */
797  {
799  }
800 
801  debug_on("SAFESCALE_DISTRIBUTOR_DEBUG_LEVEL");
802 
803  /* Get the READ, WRITE, IN and OUT regions of the module */
807 
808  /* Do the job */
809  pips_debug(2, "BEGIN of SAFESCALE_DISTRIBUTOR\n");
810  /* Restructuring code to avoid imbricated sequences if some portions are found to allow more than one INIT */
811  simple_restructure_statement(module_stat);
812  distribute(module_stat, module);
813  pips_debug(2, "END of SAFESCALE_DISTRIBUTOR\n");
814 
815  print_statement(module_stat);
816 
817  pips_assert("Statement structure is consistent after SAFESCALE_DISTRIBUTOR", gen_consistent_p((gen_chunk*) module_stat));
818  pips_assert("Statement is consistent after SAFESCALE_DISTRIBUTOR", statement_consistent_p(module_stat));
819 
820  /* Reorder the module because new statements have been added */
821  module_reorder(module_stat);
822 
823  DB_PUT_MEMORY_RESOURCE(DBR_CODE, module_name, module_stat);
824  DB_PUT_MEMORY_RESOURCE(DBR_CALLEES, module_name, compute_callees(module_stat));
825 
826  /* Update/release resources */
836 
837  debug_off();
838 
839  return true;
840 }
call make_call(entity a1, list a2)
Definition: ri.c:269
parameter make_parameter(type a1, mode a2, dummy a3)
Definition: ri.c:1495
mode make_mode(enum mode_utype tag, void *val)
Definition: ri.c:1350
type copy_type(type p)
TYPE.
Definition: ri.c:2655
storage make_storage(enum storage_utype tag, void *val)
Definition: ri.c:2273
ram make_ram(entity a1, entity a2, intptr_t a3, list a4)
Definition: ri.c:1999
bool statement_consistent_p(statement p)
Definition: ri.c:2195
language copy_language(language p)
LANGUAGE.
Definition: ri.c:1202
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
value copy_value(value p)
VALUE.
Definition: ri.c:2784
storage make_storage_formal(formal _field_)
Definition: ri.c:2282
instruction make_instruction(enum instruction_utype tag, void *val)
Definition: ri.c:1166
dummy make_dummy_unknown(void)
Definition: ri.c:617
synchronization make_synchronization_none(void)
Definition: ri.c:2424
formal make_formal(entity a1, intptr_t a2)
Definition: ri.c:1067
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
bdt base
Current expression.
Definition: bdt_read_paf.c:100
callees compute_callees(const statement stat)
Recompute the callees of a module statement.
Definition: callgraph.c:355
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
int compare_effect_reference(effect *e1, effect *e2)
int compare_effect_reference(e1, e2):
Definition: compare.c:210
void simple_restructure_statement(statement)
A simple cleaning of the control graph without major topological restructuring.
static entity new_variable
entity to be replaced, the primary?
Definition: dynamic.c:860
#define region_entity(reg)
#define REGION
#define region
simulation of the type region
#define region_scalar_p(reg)
list region_must_union(region r1, region r2)
computes the must union of two combinable array regions
list RegionsEntitiesInfDifference(list l1, list l2, bool(*difference_combinable_p)(effect, effect))
list RegionsEntitiesInfDifference(list l1, l2) input : two lists of regions output : a list of region...
list regions_write_regions(list)
list regions_read_regions(list)
void print_regions(list)
void get_regions_properties(void)
list regions_dup(list)
void set_rw_effects(statement_effects)
bool w_r_combinable_p(effect, effect)
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)
bool w_w_combinable_p(effect, effect)
list load_statement_out_regions(statement)
list load_statement_in_regions(statement)
void reset_cumulated_rw_effects(void)
list load_statement_local_regions(statement)
void reset_rw_effects(void)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#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
static void check_if_statement_contains_comment(statement s, void *a_context)
lint
static string get_externalized_function_param_name(entity variable, int param_nb)
Return EXTERNALIZED_FUNCTION_PARAM_NAME.
static entity dynamic_area
Main phase for block code externalization.
static entity create_module_with_statement(statement stat, string new_module_name, list l_params, list l_priv)
Dynamically build a new module with specified statement.
static list get_statements_with_comments_containing(string comment_portion, statement stat)
Building a list with statements containing comments.
static void add_parameter_variable_to_module(reference ref, entity module, statement stat, string new_module_name, int param_nb)
Declare in the newly created module a new variable and replace all occurences to the old variable by ...
static entity create_private_variable_for_new_module(entity a_variable, string new_name, string new_module_name, entity module)
Create a private variable in specified module.
static void replace_in_sequence_statement_with(statement old_stat, statement new_stat, statement root_stat)
Replace statement old_stat by statement new_stat and assert that this statement is contained in a seq...
static string get_externalized_function_private_param_name(entity variable)
Return EXTERNALIZED_FUNCTION_PRIVATE_PARAM_NAME.
static list references_for_regions(list l_regions)
Return a list of references corresponding to a list of regions.
static void distribute_code(string function_name, statement externalized_code, statement module_stat, list l_params, list l_priv)
Externalize a specified code portion.
static void search_sequence_containing(statement s, void *a_context)
Get sequence containing a searched context.
static list compute_regions_union(list l_in, list l_out)
Compute union of exact regions.
static bool compute_distribution_context(list l_stats, statement module_stat, entity module, hash_table *ht_stats, hash_table *ht_params, hash_table *ht_private, hash_table *ht_in_regions, hash_table *ht_out_regions)
Compute distribution context for statement externalized_code.
static string get_externalized_and_analyzed_function_name(statement stat, int *stats_nb)
Return the identified function name of the externalized portion of code by searching comment matching...
static void distribute(statement module_stat, entity module)
Distribute for main module module with root statement stat.
static entity create_parameter_variable_for_new_module(entity a_variable, string new_name, string new_module_name, entity module, int param_nb)
Create a variable declared as a parameter in specified module.
static statement sequence_statement_containing(statement root_statement, statement searched_stat)
Get statement containing a searched statement.
bool safescale_distributor(const char *module_name)
externalization.c
static void add_private_variable_to_module(reference ref, entity module, statement stat, string new_module_name)
Declare in the newly created module a new variable and replace all occurences to the old variable by ...
static bool internal_compute_distribution_context(statement externalized_code, hash_table *ht_params, hash_table *ht_private, hash_table *ht_in_regions, hash_table *ht_out_regions, void *key_value)
Compute internal distribution context for statement externalized_code.
static entity a_variable
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
Definition: genC.h:285
int gen_consistent_p(gen_chunk *obj)
GEN_CONSISTENT_P dynamically checks the type correctness of OBJ.
Definition: genClib.c:2398
void * malloc(YYSIZE_T)
void free(void *)
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
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
void replace_reference(void *s, reference old, entity new)
Replace an old reference by a reference to a new entity in a statement.
Definition: replace.c:124
bool gen_true2(__attribute__((unused)) gen_chunk *u1, __attribute__((unused)) void *u2)
Definition: genClib.c:2785
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 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
gen_chunk gen_nth(int n, const list l)
to be used as ENTITY(gen_nth(3, l))...
Definition: list.c:710
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
void gen_sort_list(list l, gen_cmp_func_t compare)
Sorts a list of gen_chunks in place, to avoid allocations...
Definition: list.c:796
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
bool statement_with_empty_comment_p(statement)
Return true if the statement has an empty statement:
Definition: statement.c:126
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:449
void hash_put(hash_table htp, const void *key, const void *val)
This functions stores a couple (key,val) in the hash table pointed to by htp.
Definition: hash.c:364
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
bool hash_defined_p(const hash_table htp, const void *key)
true if key has e value in htp.
Definition: hash.c:484
bool add_new_module(const char *module_name, entity module, statement stat, bool is_fortran)
Add the new resource files associated to a module with its more-or-less correct code.
Definition: initializer.c:553
bool prettyprint_language_is_fortran_p()
Definition: language.c:75
#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 pips_user_error
Definition: misc-local.h:147
#define DYNAMIC_AREA_LOCAL_NAME
Definition: naming-local.h:69
#define MODULE_SEP_STRING
Definition: naming-local.h:30
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define HASH_MAP(k, v, code, ht)
Definition: newgen_hash.h:60
@ hash_pointer
Definition: newgen_hash.h:32
void * gen_find_tabulated(const char *, int)
Definition: tabulated.c:218
#define UU
Definition: newgen_types.h:98
int(* gen_cmp_func_t)(const void *, const void *)
Definition: newgen_types.h:114
#define EXTERNALIZED_CODE_PRAGMA_CALL
#define EXTERNALIZED_FUNCTION_PRIVATE_PARAM_NAME
#define EXTERNALIZED_FUNCTION_PARAM_NAME
Stuff for distribution controlization.
static char * module
Definition: pips.c:74
void print_reference(reference r)
Definition: expression.c:142
#define print_region(x)
Definition: print.c:343
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
void set_bool_property(const char *, bool)
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
#define make_entity(n, t, s, i)
#define module_language(e)
implemented as a macro to allow lhs
#define module_functional_parameters(func)
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
entity FindEntity(const char *package, const char *name)
Retrieve an entity from its package/module name and its local name.
Definition: entity.c:1503
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
entity FindOrCreateEntity(const char *package, const char *local_name)
Problem: A functional global entity may be referenced without parenthesis or CALL keyword in a functi...
Definition: entity.c:1586
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
string entity_global_name(entity e)
Used instead of the macro to pass as formal argument.
Definition: entity.c:464
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
entity entity_empty_label(void)
Definition: entity.c:1105
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
bool entity_module_p(entity e)
Definition: entity.c:683
expression make_entity_expression(entity e, cons *inds)
Definition: expression.c:176
int add_variable_to_area(entity, entity)
Definition: variable.c:1376
@ is_basic_overloaded
Definition: ri.h:574
#define REFERENCE(x)
REFERENCE.
Definition: ri.h:2296
#define reference_variable(x)
Definition: ri.h:2326
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define statement_ordering(x)
Definition: ri.h:2454
@ is_mode_reference
Definition: ri.h:1676
#define basic_tag(x)
Definition: ri.h:613
#define type_variable(x)
Definition: ri.h:2949
#define entity_storage(x)
Definition: ri.h:2794
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define code_declarations(x)
Definition: ri.h:784
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
@ is_storage_ram
Definition: ri.h:2492
#define entity_undefined_p(x)
Definition: ri.h:2762
#define entity_undefined
Definition: ri.h:2761
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_sequence
Definition: ri.h:1469
#define instruction_tag(x)
Definition: ri.h:1511
#define PARAMETER(x)
PARAMETER.
Definition: ri.h:1788
#define sequence_statements(x)
Definition: ri.h:2360
#define statement_extensions(x)
Definition: ri.h:2464
#define value_code(x)
Definition: ri.h:3067
#define instruction_sequence(x)
Definition: ri.h:1514
#define statement_instruction(x)
Definition: ri.h:2458
#define statement_comments(x)
Definition: ri.h:2456
#define entity_type(x)
Definition: ri.h:2792
#define statement_number(x)
Definition: ri.h:2452
#define entity_domain
newgen_syntax_domain_defined
Definition: ri.h:410
#define variable_basic(x)
Definition: ri.h:3120
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
#define storage_undefined
Definition: ri.h:2476
#define entity_initial(x)
Definition: ri.h:2796
#define EXTERNALIZED_CODE_PRAGMA_ANALYZED_TOP
char * strdup()
char * variable_name(Variable v)
polynome_ri.c
Definition: polynome_ri.c:73
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
#define ifdebug(n)
Definition: sg.c:47
static string buffer
Definition: string.c:113
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
Definition: delay.c:253
void free_value_mappings(void)
Normal call to free the mappings.
Definition: value.c:1212
A gen_chunk is used to store every object.
Definition: genC.h:58
list module_declarations(entity m)
High-level functions about modules, using pipsdbm and ri-util and some global variables assumed prope...
Definition: module.c:58