PIPS
phrase_distributor.c File Reference
#include <stdio.h>
#include <ctype.h>
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "effects.h"
#include "resources.h"
#include "misc.h"
#include "ri-util.h"
#include "prettyprint.h"
#include "syntheses.h"
#include "effects-util.h"
#include "pipsdbm.h"
#include "text-util.h"
#include "properties.h"
#include "dg.h"
#include "transformer.h"
#include "graph.h"
#include "ray_dte.h"
#include "sommet.h"
#include "sg.h"
#include "polyedre.h"
#include "semantics.h"
#include "control.h"
#include "callgraph.h"
#include "preprocessor.h"
#include "pipsmake.h"
#include "phrase_tools.h"
#include "effects-generic.h"
#include "effects-simple.h"
#include "effects-convex.h"
#include "phrase_distribution.h"
+ Include dependency graph for phrase_distributor.c:

Go to the source code of this file.

Typedefs

typedef dg_arc_label arc_label
 
typedef dg_vertex_label vertex_label
 

Functions

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. More...
 
string get_function_name_by_searching_tag (statement stat, const char *tag)
 Return the identified function name of the externalized portion of code by searching comment matching tag. More...
 
static void remove_begin_tag (statement stat, string function_name)
 Remove begin tag for statement stat and function function_name. More...
 
static void remove_end_tag (statement stat, string function_name)
 Remove end tag for statement stat and function function_name. More...
 
static statement isolate_code_portion (statement begin_tag_statement, statement end_tag_statement, statement sequence_statement)
 At this point, we have a sequence statement sequence_statement which contains a statement with a begin tag and a statement with a end tag. More...
 
list identify_analyzed_statements_to_distribute (statement stat)
 This function return a list of statements that were previously marked for externalization during phase PHRASE_DISTRIBUTOR_INIT. More...
 
static list identify_statements_to_distribute (statement module_stat)
 This function return a list of statements that are marked for externalization. More...
 
static void distribute_code (string function_name, statement externalized_code, statement module_stat, list l_params, list l_priv)
 This function is called after identification and isolation of a portion of code to externalize. More...
 
static void distribute (statement module_stat, entity module)
 Main function for PHRASE_DISTRIBUTION: phrase distribution for main module module, with root statement stat. More...
 
static void prepare_distribute (statement module_stat)
 Main function for PHRASE_DISTRIBUTION_INIT: phrase distribution for module module_stat. More...
 
static string get_externalized_function_param_name (entity variable, int param_nb)
 
static string get_externalized_function_private_param_name (entity variable)
 
static entity create_parameter_variable_for_new_module (entity a_variable, string new_name, string new_module_name, entity module, int param_nb)
 Creates a variable declared as a parameter in specified module. More...
 
entity create_private_variable_for_new_module (entity a_variable, const char *new_name, const char *new_module_name, entity module)
 Creates a private variable in specified module. More...
 
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 (which will be a parameter of the module), and replace all occurences to the old variable by the new created. More...
 
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 (which will be a private to the module), and replace all occurences to the old variable by the new created. More...
 
bool phrase_distributor_init (const char *module_name)
 
bool phrase_distributor (const char *module_name)
 

Variables

static entity dynamic_area = entity_undefined
 

Typedef Documentation

◆ arc_label

Definition at line 50 of file phrase_distributor.c.

◆ vertex_label

Definition at line 51 of file phrase_distributor.c.

Function Documentation

◆ add_parameter_variable_to_module()

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 (which will be a parameter of the module), and replace all occurences to the old variable by the new created.

Assert that entity represent a value code

Get the variable name

trdup("")

Parameters
refef
moduleodule
stattat
new_module_nameStatement of the new module
param_nbaram_nb

Definition at line 633 of file phrase_distributor.c.

638 {
639  parameter new_parameter;
641  list module_parameters;
643  string variable_name;
644 
645  pips_debug(2, "Registering parameter: %s\n", entity_local_name(reference_variable(ref)));
646 
647  /* Assert that entity represent a value code */
648  pips_assert("It is a module", entity_module_p(module));
649 
650  /* Get the variable name */
653 
656  new_module_name,
657  module,
658  param_nb);
659 
661 
663 
666 
667  new_parameter = make_parameter (entity_type(new_variable),
669  /*strdup("")*/make_dummy_identifier(new_variable));
670 
672 
674  = CONS(PARAMETER, new_parameter, module_parameters);
675 
676 }
dummy make_dummy_identifier(entity _field_)
Definition: ri.c:620
parameter make_parameter(type a1, mode a2, dummy a3)
Definition: ri.c:1495
mode make_mode_reference(void)
Definition: ri.c:1356
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
static entity new_variable
entity to be replaced, the primary?
Definition: dynamic.c:860
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
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
#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_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
static string get_externalized_function_param_name(entity variable, int param_nb)
static entity create_parameter_variable_for_new_module(entity a_variable, string new_name, string new_module_name, entity module, int param_nb)
Creates a variable declared as a parameter in specified module.
static char * module
Definition: pips.c:74
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_module_p(entity e)
Definition: entity.c:683
#define reference_variable(x)
Definition: ri.h:2326
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define type_functional(x)
Definition: ri.h:2952
#define code_declarations(x)
Definition: ri.h:784
#define functional_parameters(x)
Definition: ri.h:1442
#define PARAMETER(x)
PARAMETER.
Definition: ri.h:1788
#define value_code(x)
Definition: ri.h:3067
#define entity_type(x)
Definition: ri.h:2792
#define entity_initial(x)
Definition: ri.h:2796
char * variable_name(Variable v)
polynome_ri.c
Definition: polynome_ri.c:73
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
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

References code_declarations, CONS, create_parameter_variable_for_new_module(), ENTITY, entity_initial, entity_local_name(), entity_module_p(), entity_type, functional_parameters, get_externalized_function_param_name(), make_dummy_identifier(), make_mode_reference(), make_parameter(), module, module_declarations(), new_variable, PARAMETER, pips_assert, pips_debug, ref, reference_variable, replace_reference(), type_functional, value_code, and variable_name().

Referenced by create_module_with_statement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ add_private_variable_to_module()

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 (which will be a private to the module), and replace all occurences to the old variable by the new created.

Assert that entity represent a value code

Get the variable name

Creates the variable

Parameters
refef
moduleodule
stattat
new_module_nameStatement of the new module

Definition at line 683 of file phrase_distributor.c.

687 {
690  string variable_name;
691 
692  pips_debug(2, "Registering private variable: %s\n", entity_local_name(reference_variable(ref)));
693 
694  /* Assert that entity represent a value code */
695  pips_assert("It is a module", entity_module_p(module));
696 
697  /* Get the variable name */
699 
700  /* Creates the variable */
701  new_variable
704  new_module_name,
705  module);
706 
708 
710 
713 
714 }
entity create_private_variable_for_new_module(entity a_variable, const char *new_name, const char *new_module_name, entity module)
Creates a private variable in specified module.
static string get_externalized_function_private_param_name(entity variable)

References code_declarations, CONS, create_private_variable_for_new_module(), ENTITY, entity_initial, entity_local_name(), entity_module_p(), get_externalized_function_private_param_name(), module, module_declarations(), new_variable, pips_assert, pips_debug, ref, reference_variable, replace_reference(), value_code, and variable_name().

Referenced by create_module_with_statement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ create_module_with_statement()

static entity create_module_with_statement ( statement  stat,
string  new_module_name,
list  l_params,
list  l_priv 
)
static

Dynamically build a new module with specified statement.

After creation, return it.

Deal with private variables

Definition at line 720 of file phrase_distributor.c.

724 {
725  entity new_module;
726  int param_nb = 0;
727 
728  pips_debug(2, "Creating new module: [%s]\n", new_module_name);
729 
730  new_module = make_empty_subroutine(new_module_name,make_language_unknown());
731 
732  /* Deal with private variables */
735  new_module,
736  stat,
737  new_module_name);
738  }
739 
740  // Deal with parameters variables
741  param_nb = gen_length(l_params);
744  new_module,
745  stat,
746  new_module_name,
747  param_nb);
748  param_nb--;
749  }
750 
751  pips_debug(2, "Making new module: [%s]\n", new_module_name);
752  ifdebug(5) {
753  pips_debug(5, "With statement: \n");
754  print_statement (stat);
755  }
756  text t = text_named_module(new_module, new_module, stat);
758 
759  free_text(t);
760 
761  return new_module;
762 }
language make_language_unknown(void)
Definition: ri.c:1259
void free_text(text p)
Definition: text.c:74
string compilation_unit_of_module(const char *)
The output is undefined if the module is referenced but not defined in the workspace,...
Definition: module.c:350
const char * get_current_module_name(void)
Get the name of the current module.
Definition: static.c:121
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
size_t gen_length(const list l)
Definition: list.c:150
#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
bool add_new_module_from_text(const char *module_name, text code_text, bool is_fortran, const char *compilation_unit_name)
Add the new resource files associated to a module with its more-or-less correct code.
Definition: initializer.c:431
list references_for_regions(list)
Return a list of references corresponding to a list of regions.
Definition: phrase_tools.c:603
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 (which will be a private to the module),...
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 (which will be a parameter of the module),...
text text_named_module(entity, entity, statement)
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
entity make_empty_subroutine(const char *name, language l)
Definition: entity.c:268
bool fortran_module_p(entity m)
Test if a module is in Fortran.
Definition: entity.c:2799
#define REFERENCE(x)
REFERENCE.
Definition: ri.h:2296
#define ifdebug(n)
Definition: sg.c:47

References add_new_module_from_text(), add_parameter_variable_to_module(), add_private_variable_to_module(), compilation_unit_of_module(), FOREACH, fortran_module_p(), free_text(), gen_length(), get_current_module_entity(), get_current_module_name(), ifdebug, make_empty_subroutine(), make_language_unknown(), pips_debug, print_statement(), ref, REFERENCE, references_for_regions(), and text_named_module().

Referenced by distribute_code().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ create_parameter_variable_for_new_module()

static entity create_parameter_variable_for_new_module ( entity  a_variable,
string  new_name,
string  new_module_name,
entity  module,
int  param_nb 
)
static

Creates a variable declared as a parameter in specified module.

This entity does not exist, we can safely create it

Definition at line 551 of file phrase_distributor.c.

556 {
558 
559  if ((gen_find_tabulated(concatenate(new_module_name,
561  new_name,
562  NULL),
564  {
565  /* This entity does not exist, we can safely create it */
566 
567  new_variable = make_entity (strdup(concatenate(new_module_name,
569  new_name, NULL)),
573 
574  return new_variable;
575  }
576  else
577  {
578  pips_internal_error("Entity already exist: %s", new_name);
579  return NULL;
580  }
581 }
type copy_type(type p)
TYPE.
Definition: ri.c:2655
value copy_value(value p)
VALUE.
Definition: ri.c:2784
storage make_storage_formal(formal _field_)
Definition: ri.c:2282
formal make_formal(entity a1, intptr_t a2)
Definition: ri.c:1067
static entity a_variable
#define pips_internal_error
Definition: misc-local.h:149
#define MODULE_SEP_STRING
Definition: naming-local.h:30
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 make_entity(n, t, s, i)
#define entity_undefined
Definition: ri.h:2761
#define entity_domain
newgen_syntax_domain_defined
Definition: ri.h:410
char * strdup()

References a_variable, concatenate(), copy_type(), copy_value(), entity_domain, entity_initial, entity_type, entity_undefined, gen_find_tabulated(), make_entity, make_formal(), make_storage_formal(), module, MODULE_SEP_STRING, new_variable, pips_internal_error, and strdup().

Referenced by add_parameter_variable_to_module().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ create_private_variable_for_new_module()

entity create_private_variable_for_new_module ( entity  a_variable,
const char *  new_name,
const char *  new_module_name,
entity  module 
)

Creates a private variable in specified module.

This entity does not exist, we can safely create it

Parameters
a_variable_variable
new_nameew_name
new_module_nameew_module_name
moduleodule

Definition at line 586 of file phrase_distributor.c.

590 {
592  entity a;
593  basic base;
594 
595  if ((gen_find_tabulated(concatenate(new_module_name,
597  new_name,
598  NULL),
600  {
601  /* This entity does not exist, we can safely create it */
602 
603  new_variable = make_entity (strdup(concatenate(new_module_name,
605  new_name, NULL)),
609  a = FindEntity(new_module_name, DYNAMIC_AREA_LOCAL_NAME);
613  make_ram(module, a,
616  NIL));
617  pips_debug(2, "Created new private variable: %s\n", entity_global_name(new_variable));
618  return new_variable;
619  }
620  else
621  {
622  pips_internal_error("Entity already exist: %s", new_name);
623  return NULL;
624  }
625 }
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
bdt base
Current expression.
Definition: bdt_read_paf.c:100
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define DYNAMIC_AREA_LOCAL_NAME
Definition: naming-local.h:69
entity FindEntity(const char *package, const char *name)
Retrieve an entity from its package/module name and its local name.
Definition: entity.c:1503
string entity_global_name(entity e)
Used instead of the macro to pass as formal argument.
Definition: entity.c:464
int add_variable_to_area(entity, entity)
Definition: variable.c:1376
@ is_basic_overloaded
Definition: ri.h:574
#define basic_tag(x)
Definition: ri.h:613
#define type_variable(x)
Definition: ri.h:2949
#define entity_storage(x)
Definition: ri.h:2794
@ is_storage_ram
Definition: ri.h:2492
#define variable_basic(x)
Definition: ri.h:3120
#define storage_undefined
Definition: ri.h:2476

References a_variable, add_variable_to_area(), base, basic_tag, concatenate(), copy_type(), copy_value(), DYNAMIC_AREA_LOCAL_NAME, entity_domain, entity_global_name(), entity_initial, entity_storage, entity_type, entity_undefined, FindEntity(), gen_find_tabulated(), is_basic_overloaded, is_storage_ram, make_entity, make_ram(), make_storage(), module, MODULE_SEP_STRING, new_variable, NIL, pips_debug, pips_internal_error, storage_undefined, strdup(), type_variable, and variable_basic.

Referenced by add_private_variable_to_module().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ distribute()

static void distribute ( statement  module_stat,
entity  module 
)
static

Main function for PHRASE_DISTRIBUTION: phrase distribution for main module module, with root statement stat.

Definition at line 478 of file phrase_distributor.c.

480 {
481  list l_stats;
482  hash_table ht_stats;
483  hash_table ht_params;
484  hash_table ht_private;
485  hash_table ht_in_regions;
486  hash_table ht_out_regions;
487 
488  l_stats = identify_analyzed_statements_to_distribute (module_stat);
489 
491  module_stat,
492  module,
493  &ht_stats,
494  &ht_params,
495  &ht_private,
496  &ht_in_regions,
497  &ht_out_regions);
498 
499  HASH_MAP (function_name, stat, {
500  distribute_code (function_name,
501  stat,
502  module_stat,
503  hash_get(ht_params,function_name),
504  hash_get(ht_private,function_name));
505  },ht_stats);
506 
507  hash_table_free(ht_stats);
508  hash_table_free(ht_params);
509  hash_table_free(ht_private);
510  hash_table_free(ht_in_regions);
511  hash_table_free(ht_out_regions);
512 }
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)
This function is called during PHRASE distribution.
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_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
#define HASH_MAP(k, v, code, ht)
Definition: newgen_hash.h:60
list identify_analyzed_statements_to_distribute(statement stat)
This function return a list of statements that were previously marked for externalization during phas...
static void distribute_code(string function_name, statement externalized_code, statement module_stat, list l_params, list l_priv)
This function is called after identification and isolation of a portion of code to externalize.

References compute_distribution_context(), distribute_code(), hash_get(), HASH_MAP, hash_table_free(), identify_analyzed_statements_to_distribute(), and module.

Referenced by phrase_distributor().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ distribute_code()

static void distribute_code ( string  function_name,
statement  externalized_code,
statement  module_stat,
list  l_params,
list  l_priv 
)
static

This function is called after identification and isolation of a portion of code to externalize.

Externalization of specified code is done here.

Definition at line 398 of file phrase_distributor.c.

403 {
404  entity new_module;
405  statement call_statement;
406  list call_params;
407  string call_comments;
408 
409  new_module
410  = create_module_with_statement (externalized_code,
411  function_name,
412  l_params,
413  l_priv);
414 
415  call_params = NIL;
416  MAP (REFERENCE, ref, {
417  call_params = CONS(EXPRESSION, entity_to_expression(reference_variable(ref)), call_params);
418  }, references_for_regions(l_params));
419 
420  // Insert an analyzed tag
421  {
422  asprintf (&call_comments,
423  (concatenate("! ",
425  "\n",
426  NULL)),
427  function_name);
428  }
429 
430  call_statement = make_statement(entity_empty_label(),
431  statement_number(externalized_code),
432  statement_ordering(externalized_code),
433  call_comments,
435  make_call(new_module,call_params)),
436  NIL,NULL,
437  statement_extensions(externalized_code), make_synchronization_none());
438 
439  ifdebug(5) {
440  pips_debug(5, "BEFORE REPLACING\n");
441  pips_debug(5, "externalized_code=\n");
442  print_statement(externalized_code);
443  pips_debug(5, "call_statement=\n");
444  print_statement(call_statement);
445  pips_debug(5, "module_stat=\n");
446  print_statement(module_stat);
447  }
448 
449  replace_in_sequence_statement_with(externalized_code,
450  call_statement,
451  module_stat);
452 
453  ifdebug(5) {
454  pips_debug(5, "AFTER REPLACING\n");
455  pips_debug(5, "externalized_code=\n");
456  print_statement(externalized_code);
457  pips_debug(5, "call_statement=\n");
458  print_statement(call_statement);
459  pips_debug(5, "module_stat=\n");
460  print_statement(module_stat);
461  }
462 
463  pips_assert("Module structure is consistent after DISTRIBUTE_CODE",
464  gen_consistent_p((gen_chunk*)new_module));
465 
466  pips_assert("Statement structure is consistent after DISTRIBUTE_CODE",
467  gen_consistent_p((gen_chunk*)externalized_code));
468 
469  pips_assert("Statement is consistent after DISTRIBUTE_CODE",
470  statement_consistent_p(externalized_code));
471 
472  pips_debug(5, "Code distribution for : [%s] is DONE\n", function_name);
473 }
call make_call(entity a1, list a2)
Definition: ri.c:269
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(enum instruction_utype tag, void *val)
Definition: ri.c:1166
synchronization make_synchronization_none(void)
Definition: ri.c:2424
int gen_consistent_p(gen_chunk *obj)
GEN_CONSISTENT_P dynamically checks the type correctness of OBJ.
Definition: genClib.c:2398
#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
#define asprintf
Definition: misc-local.h:225
void replace_in_sequence_statement_with(statement, statement, statement)
Replace statement old_stat by statement new_stat, asserting that this statement is contained in a seq...
Definition: phrase_tools.c:554
#define EXTERNALIZED_CODE_PRAGMA_CALL
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.
entity entity_empty_label(void)
Definition: entity.c:1105
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
#define statement_ordering(x)
Definition: ri.h:2454
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
@ is_instruction_call
Definition: ri.h:1474
#define statement_extensions(x)
Definition: ri.h:2464
#define statement_number(x)
Definition: ri.h:2452
A gen_chunk is used to store every object.
Definition: genC.h:58

References asprintf, concatenate(), CONS, create_module_with_statement(), entity_empty_label(), entity_to_expression(), EXPRESSION, EXTERNALIZED_CODE_PRAGMA_CALL, gen_consistent_p(), ifdebug, is_instruction_call, make_call(), make_instruction(), make_statement(), make_synchronization_none(), MAP, NIL, pips_assert, pips_debug, print_statement(), ref, REFERENCE, reference_variable, references_for_regions(), replace_in_sequence_statement_with(), statement_consistent_p(), statement_extensions, statement_number, and statement_ordering.

Referenced by distribute().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_externalized_function_param_name()

static string get_externalized_function_param_name ( entity  variable,
int  param_nb 
)
static

Definition at line 526 of file phrase_distributor.c.

527 {
528  char *buffer;
529  asprintf(&buffer,
532  param_nb);
533  return (buffer);
534 }
#define EXTERNALIZED_FUNCTION_PARAM_NAME
Stuff for distribution controlization.
static string buffer
Definition: string.c:113

References asprintf, buffer, entity_local_name(), and EXTERNALIZED_FUNCTION_PARAM_NAME.

Referenced by add_parameter_variable_to_module().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_externalized_function_private_param_name()

static string get_externalized_function_private_param_name ( entity  variable)
static

Definition at line 539 of file phrase_distributor.c.

540 {
541  char *buffer;
542  asprintf(&buffer,
545  return (buffer);
546 }
#define EXTERNALIZED_FUNCTION_PRIVATE_PARAM_NAME

References asprintf, buffer, entity_local_name(), and EXTERNALIZED_FUNCTION_PRIVATE_PARAM_NAME.

Referenced by add_private_variable_to_module().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_function_name_by_searching_tag()

string get_function_name_by_searching_tag ( statement  stat,
const char *  tag 
)

Return the identified function name of the externalized portion of code by searching comment matching tag.

phrase_distributor.c

Parameters
stattat
tagag

Definition at line 82 of file phrase_distributor.c.

84 {
85  string comments;
86  string searched_string;
87  string comment_portion = strdup(tag);
88  char* function_name = NULL;
89  char* next_line;
91 
92  ifdebug(5) {
93  pips_debug(5, "BEGIN get_function_name_by_searching_tag [%s] on \n", tag);
94  print_statement(stat);
95  }
96 
99  }
100 
101  if (!statement_with_empty_comment_p(stat)) {
102  searched_string = strdup(comment_portion);
103  searched_string[strcspn(comment_portion, "%s")] = '\0';
104  comments = strdup(statement_comments(stat));
105  next_line = strtok (comments, "\n");
106  if (next_line != NULL) {
107  do {
108  string first_occurence = strstr(next_line,searched_string);
109  if (first_occurence != NULL) {
110  function_name = malloc(256);
111  sscanf (first_occurence, comment_portion, function_name);
112  pips_debug(5, "Found function: [%s]\n", function_name);
113  }
114  next_line = strtok(NULL, "\n");
115  }
116  while (next_line != NULL);
117  }
118  }
119 
120  pips_debug(5, "END get_function_name_by_searching_tag [%s] on \n", tag);
121  return function_name;
122 }
void * malloc(YYSIZE_T)
gen_chunk gen_nth(int n, const list l)
to be used as ENTITY(gen_nth(3, l))...
Definition: list.c:710
bool statement_with_empty_comment_p(statement)
Return true if the statement has an empty statement:
Definition: statement.c:126
int tag
TAG.
Definition: newgen_types.h:92
@ is_instruction_sequence
Definition: ri.h:1469
#define instruction_tag(x)
Definition: ri.h:1511
#define sequence_statements(x)
Definition: ri.h:2360
#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 STATEMENT(x)
STATEMENT.
Definition: ri.h:2413

References gen_nth(), ifdebug, instruction_sequence, instruction_tag, is_instruction_sequence, malloc(), pips_debug, print_statement(), sequence_statements, STATEMENT, statement_comments, statement_instruction, statement_with_empty_comment_p(), and strdup().

Referenced by get_externalizable_function_name(), and get_externalized_function_name().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ identify_analyzed_statements_to_distribute()

list identify_analyzed_statements_to_distribute ( statement  stat)

This function return a list of statements that were previously marked for externalization during phase PHRASE_DISTRIBUTOR_INIT.

We identify all the statement containing an analyzed tag

Parameters
stattat

Definition at line 288 of file phrase_distributor.c.

289 {
290  /* We identify all the statement containing an analyzed tag */
292  stat);
293 
294 }
list get_statements_with_comments_containing(const char *, statement)
Definition: phrase_tools.c:481
#define EXTERNALIZED_CODE_PRAGMA_ANALYZED

References EXTERNALIZED_CODE_PRAGMA_ANALYZED, and get_statements_with_comments_containing().

Referenced by comEngine_distribute(), and distribute().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ identify_statements_to_distribute()

static list identify_statements_to_distribute ( statement  module_stat)
static

This function return a list of statements that are marked for externalization.

A well-formed externalizable code must be one or more continuous statements defined in a sequence statement framed with comments containing tags EXTERNALIZED_CODE_PRAGMA_BEGIN and EXTERNALIZED_CODE_PRAGMA_END

We identify all the statement containing a begin tag

We restructure the code to avoid imbricated sequences only if some portions are found (to allow more than one INIT)

We identify again (after code restructuration) all the statement containing a begin tag

We check that all those statements are contained in a sequence

Definition at line 304 of file phrase_distributor.c.

305 {
306  list statements_containing_begin_tag = NIL;
307  list statements_contained_in_a_sequence = NIL;
308  list statements_to_distribute = NIL;
309 
310  /* We identify all the statement containing a begin tag */
311  statements_containing_begin_tag
313  module_stat);
314  /* We restructure the code to avoid imbricated sequences only if
315  * some portions are found (to allow more than one INIT) */
316  if (gen_length(statements_containing_begin_tag) > 0) {
317  simple_restructure_statement(module_stat);
318  }
319 
320  /* We identify again (after code restructuration) all the statement
321  * containing a begin tag */
322  statements_containing_begin_tag = NIL;
323  statements_containing_begin_tag
325  module_stat);
326 
327  /* We check that all those statements are contained in a sequence */
328  MAP (STATEMENT, s, {
329  ifdebug(5) {
330  pips_debug(5, "Potential externalizable statement:\n");
331  print_statement(s);
332  }
333  if (statement_is_contained_in_a_sequence_p (module_stat,s)) {
334  statements_contained_in_a_sequence
335  = CONS (STATEMENT,
336  s,
337  statements_contained_in_a_sequence);
338  }
339  else {
340  pips_user_warning("Malformed externalized code portion identified. Ignored.\n");
341  }
342  }, statements_containing_begin_tag);
343 
344  /* */
345  FOREACH (STATEMENT, s, statements_contained_in_a_sequence){
346  statement sequence_statement;
347  string function_name;
348  string end_tag;
349  list potential_end_statement = NIL;
350  sequence_statement = sequence_statement_containing (module_stat,s);
351  ifdebug(5) {
352  pips_debug(5, "Potential externalizable statement contained in a sequence \n");
353  print_statement(s);
354  }
355  function_name = get_externalizable_function_name(s);
356  if (function_name != NULL) {
357  pips_debug(5, "Name: [%s] \n", function_name);
358  asprintf (&end_tag, EXTERNALIZED_CODE_PRAGMA_END,function_name);
359  potential_end_statement
361  sequence_statement);
362  if (gen_length(potential_end_statement) == 1) {
363  statement begin_tag_statement = s;
364  statement end_tag_statement
365  = STATEMENT(gen_nth(0,potential_end_statement));
366  statement container_of_end_tag_statement
367  = sequence_statement_containing (sequence_statement, end_tag_statement);
368  if (container_of_end_tag_statement == sequence_statement) {
369  statement externalized_code
370  = isolate_code_portion (begin_tag_statement,
371  end_tag_statement,
372  sequence_statement);
373  statements_to_distribute
374  = CONS (STATEMENT,
375  externalized_code,
376  statements_to_distribute);
377  }
378  else {
379  pips_user_warning("Malformed externalized code portion identified [%s]. End tag found at a bad place!!!. Ignored.\n", function_name);
380  }
381  }
382  else {
383  pips_user_warning("Malformed externalized code portion identified [%s]. %d end tags found!!!. Ignored.\n", function_name, gen_length(potential_end_statement));
384  }
385  }
386  else {
387  pips_user_warning("Malformed externalized code portion identified [Unnamed]!!!. Ignored.\n");
388  }
389  }
390 
391  return statements_to_distribute;
392 }
void simple_restructure_statement(statement)
A simple cleaning of the control graph without major topological restructuring.
string get_externalizable_function_name(statement stat)
Return the identified function name of the externalized portion of code by searching comment matching...
#define pips_user_warning
Definition: misc-local.h:146
statement sequence_statement_containing(statement, statement)
Definition: phrase_tools.c:536
bool statement_is_contained_in_a_sequence_p(statement, statement)
Definition: phrase_tools.c:507
#define EXTERNALIZED_CODE_PRAGMA_BEGIN
#define EXTERNALIZED_CODE_PRAGMA_END
static statement isolate_code_portion(statement begin_tag_statement, statement end_tag_statement, statement sequence_statement)
At this point, we have a sequence statement sequence_statement which contains a statement with a begi...

References asprintf, CONS, EXTERNALIZED_CODE_PRAGMA_BEGIN, EXTERNALIZED_CODE_PRAGMA_END, FOREACH, gen_length(), gen_nth(), get_externalizable_function_name(), get_statements_with_comments_containing(), ifdebug, isolate_code_portion(), MAP, NIL, pips_debug, pips_user_warning, print_statement(), sequence_statement_containing(), simple_restructure_statement(), STATEMENT, and statement_is_contained_in_a_sequence_p().

Referenced by prepare_distribute().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ isolate_code_portion()

static statement isolate_code_portion ( statement  begin_tag_statement,
statement  end_tag_statement,
statement  sequence_statement 
)
static

At this point, we have a sequence statement sequence_statement which contains a statement with a begin tag and a statement with a end tag.

The goal is to transform this statement in a sequence statement with a single statement, which is the embedded statement that will be distributed. This function returns this isolated statement

First, count the number of statements to isolate in a single statement

Insert an analyzed tag

Build new isolated sequence statement

Build new sequence containing isolated sequence statement

Rebuild the sequence in the GOOD order

Nothing to do, the code is already isolated !

Definition at line 161 of file phrase_distributor.c.

164 {
165  instruction i = statement_instruction(sequence_statement);
167  list new_seq_stats = NIL;
168  list isolated_seq_stats = NIL;
169  bool statement_to_isolate;
170  int nb_of_statements_to_isolate;
171  string function_name = get_externalizable_function_name(begin_tag_statement);
172 
173 
174  pips_assert ("sequence_statement is a sequence",
176 
177  pips_assert ("function_name is not NULL",
178  function_name != NULL);
179 
180  /* First, count the number of statements to isolate in a single statement */
181  statement_to_isolate = false;
182  nb_of_statements_to_isolate = 0;
183  MAP (STATEMENT, s, {
184 
185  if ((statement_to_isolate && (s != end_tag_statement))
186  || ((!statement_to_isolate) && (s == begin_tag_statement))) {
187  nb_of_statements_to_isolate++;
188  isolated_seq_stats = CONS(STATEMENT, s, isolated_seq_stats);
189  }
190  if (statement_to_isolate && (s == end_tag_statement)) {
191  statement_to_isolate = false;
192  }
193  if ((!statement_to_isolate) && (s == begin_tag_statement)) {
194  statement_to_isolate = true;
195  }
196 
197  }, seq_stats);
198 
199  remove_begin_tag (begin_tag_statement, function_name);
200  remove_end_tag (end_tag_statement, function_name);
201 
202  /* Insert an analyzed tag */
203  {
204  char* new_tag ;
205  asprintf (&new_tag,
206  (concatenate("! ",
208  "\n",
209  NULL)),
210  function_name,
211  nb_of_statements_to_isolate);
212  insert_comments_to_statement(begin_tag_statement, new_tag);
213  }
214 
215  pips_debug(5, "Found %d statement to isolate\n",
216  nb_of_statements_to_isolate);
217 
218  if (nb_of_statements_to_isolate > 1) {
219 
220  /* Build new isolated sequence statement */
221 
222  sequence new_sequence = make_sequence (gen_nreverse(isolated_seq_stats));
223  instruction sequence_instruction
225  new_sequence);
226  statement returned_statement
228  statement_number(sequence_statement),
229  statement_ordering(sequence_statement),
231  sequence_instruction,NIL,NULL,
232  statement_extensions(sequence_statement), make_synchronization_none());
233 
234  bool isolated_seq_stats_is_inserted = false;
235 
236  /* Build new sequence containing isolated sequence statement */
237 
238  MAP (STATEMENT, s, {
239  if ((statement_to_isolate && (s != end_tag_statement))
240  || ((!statement_to_isolate) && (s == begin_tag_statement))) {
241  if (!isolated_seq_stats_is_inserted) {
242  new_seq_stats = CONS(STATEMENT, returned_statement, new_seq_stats);
243  isolated_seq_stats_is_inserted = true;
244  }
245  }
246  else {
247  new_seq_stats = CONS(STATEMENT, s, new_seq_stats);
248  }
249  if (statement_to_isolate && (s == end_tag_statement)) {
250  statement_to_isolate = false;
251  }
252  if ((!statement_to_isolate) && (s == begin_tag_statement)) {
253  statement_to_isolate = true;
254  }
255  }, seq_stats);
256 
257  /* Rebuild the sequence in the GOOD order */
259  = gen_nreverse(new_seq_stats);
260 
261  ifdebug(5) {
262  pips_debug(5,"Isolating and returning statement:\n");
263  print_statement(returned_statement);
264  }
265 
266  return returned_statement;
267  }
268  else if (nb_of_statements_to_isolate == 1) {
269  /* Nothing to do, the code is already isolated ! */
270  ifdebug(5) {
271  pips_debug(5,"Isolating and returning statement:\n");
272  print_statement(begin_tag_statement);
273  }
274  return begin_tag_statement;
275  }
276  else {
277  pips_user_warning("Malformed externalized code portion identified. No operation to do. Ignored.\n");
278  return NULL;
279  }
280 
281 }
sequence make_sequence(list a)
Definition: ri.c:2125
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
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
static void remove_end_tag(statement stat, string function_name)
Remove end tag for statement stat and function function_name.
static void remove_begin_tag(statement stat, string function_name)
Remove begin tag for statement stat and function function_name.
#define empty_comments
Empty comments (i.e.

References asprintf, concatenate(), CONS, empty_comments, entity_empty_label(), EXTERNALIZED_CODE_PRAGMA_ANALYZED, gen_nreverse(), get_externalizable_function_name(), ifdebug, insert_comments_to_statement(), instruction_sequence, instruction_tag, is_instruction_sequence, make_instruction(), make_sequence(), make_statement(), make_synchronization_none(), MAP, NIL, pips_assert, pips_debug, pips_user_warning, print_statement(), remove_begin_tag(), remove_end_tag(), sequence_statements, STATEMENT, statement_extensions, statement_instruction, statement_number, and statement_ordering.

Referenced by identify_statements_to_distribute().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ phrase_distributor()

bool phrase_distributor ( const char *  module_name)

set and get the current properties concerning regions

get the resources

sets dynamic_area

Get the READ, WRITE, IN and OUT regions of the module

Now do the job

Reorder the module, because new statements have been added

update/release resources

Parameters
module_nameodule_name

Definition at line 816 of file phrase_distributor.c.

817 {
818  statement module_stat;
819  entity module;
820 
821  /* set and get the current properties concerning regions */
822  set_bool_property("MUST_REGIONS", true);
823  set_bool_property("EXACT_REGIONS", true);
825 
826  /* get the resources */
827  module_stat = (statement) db_get_memory_resource(DBR_CODE,
828  module_name,
829  true);
830 
832 
833  set_current_module_statement(module_stat);
835 
837  db_get_memory_resource(DBR_CUMULATED_EFFECTS, module_name, true));
839  db_get_memory_resource(DBR_PROPER_EFFECTS, module_name, true));
841 
842  /* sets dynamic_area */
846  }
847 
848  debug_on("PHRASE_DISTRIBUTOR_DEBUG_LEVEL");
849 
850  /* Get the READ, WRITE, IN and OUT regions of the module
851  */
853  db_get_memory_resource(DBR_REGIONS, module_name, true));
855  db_get_memory_resource(DBR_IN_REGIONS, module_name, true));
857  db_get_memory_resource(DBR_OUT_REGIONS, module_name, true));
858 
859  /* Now do the job */
860 
861  pips_debug(2, "BEGIN of PHRASE_DISTRIBUTOR\n");
862  distribute (module_stat, module);
863  pips_debug(2, "END of PHRASE_DISTRIBUTOR\n");
864 
865  //print_statement(module_stat);
866 
867  pips_assert("Statement structure is consistent after PHRASE_DISTRIBUTOR",
868  gen_consistent_p((gen_chunk*)module_stat));
869 
870  pips_assert("Statement is consistent after PHRASE_DISTRIBUTOR",
871  statement_consistent_p(module_stat));
872 
873  /* Reorder the module, because new statements have been added */
874  module_reorder(module_stat);
875  DB_PUT_MEMORY_RESOURCE(DBR_CODE, module_name, module_stat);
876  DB_PUT_MEMORY_RESOURCE(DBR_CALLEES, module_name,
877  compute_callees(module_stat));
878 
879  /* update/release resources */
889 
890  debug_off();
891 
892  return true;
893 }
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
void get_regions_properties(void)
void set_rw_effects(statement_effects)
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)
void reset_cumulated_rw_effects(void)
void reset_rw_effects(void)
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
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
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
#define debug_on(env)
Definition: misc-local.h:157
#define debug_off()
Definition: misc-local.h:160
static entity dynamic_area
static void distribute(statement module_stat, entity module)
Main function for PHRASE_DISTRIBUTION: phrase distribution for main module module,...
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
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
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
#define entity_undefined_p(x)
Definition: ri.h:2762
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 free_value_mappings(void)
Normal call to free the mappings.
Definition: value.c:1212

References compute_callees(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, distribute(), dynamic_area, DYNAMIC_AREA_LOCAL_NAME, entity_undefined, entity_undefined_p, FindOrCreateEntity(), free_value_mappings(), gen_consistent_p(), get_regions_properties(), module, module_local_name(), module_name(), module_name_to_entity(), module_reorder(), module_to_value_mappings(), pips_assert, pips_debug, reset_cumulated_rw_effects(), reset_current_module_entity(), reset_current_module_statement(), reset_in_effects(), reset_out_effects(), reset_proper_rw_effects(), reset_rw_effects(), set_bool_property(), set_cumulated_rw_effects(), set_current_module_entity(), set_current_module_statement(), set_in_effects(), set_out_effects(), set_proper_rw_effects(), set_rw_effects(), and statement_consistent_p().

+ Here is the call graph for this function:

◆ phrase_distributor_init()

bool phrase_distributor_init ( const char *  module_name)

get the resources

Now do the job

Reorder the module, because new statements have been added

update/release resources

Parameters
module_nameodule_name

Definition at line 768 of file phrase_distributor.c.

769 {
770 
771  /* get the resources */
772  statement stat = (statement) db_get_memory_resource(DBR_CODE,
773  module_name,
774  true);
775 
776 
779 
780  debug_on("PHRASE_DISTRIBUTOR_DEBUG_LEVEL");
781 
782  /* Now do the job */
783 
784  pips_debug(2, "BEGIN of PHRASE_DISTRIBUTOR_INIT\n");
785  prepare_distribute (stat);
786  pips_debug(2, "END of PHRASE_DISTRIBUTOR_INIT\n");
787 
788  pips_assert("Statement structure is consistent after PHRASE_DISTRIBUTOR_INIT",
789  gen_consistent_p((gen_chunk*)stat));
790 
791  pips_assert("Statement is consistent after PHRASE_DISTRIBUTOR_INIT",
792  statement_consistent_p(stat));
793 
794 
795  /* Reorder the module, because new statements have been added */
796  module_reorder(stat);
797  DB_PUT_MEMORY_RESOURCE(DBR_CODE, module_name, stat);
798  DB_PUT_MEMORY_RESOURCE(DBR_CALLEES, module_name,
799  compute_callees(stat));
800 
801  /* update/release resources */
804 
805  debug_off();
806 
807  return true;
808 }
static void prepare_distribute(statement module_stat)
Main function for PHRASE_DISTRIBUTION_INIT: phrase distribution for module module_stat.

References compute_callees(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, gen_consistent_p(), module_name(), module_name_to_entity(), module_reorder(), pips_assert, pips_debug, prepare_distribute(), reset_current_module_entity(), reset_current_module_statement(), set_current_module_entity(), set_current_module_statement(), and statement_consistent_p().

+ Here is the call graph for this function:

◆ prepare_distribute()

static void prepare_distribute ( statement  module_stat)
static

Main function for PHRASE_DISTRIBUTION_INIT: phrase distribution for module module_stat.

Definition at line 518 of file phrase_distributor.c.

519 {
520  identify_statements_to_distribute (module_stat);
521 }
static list identify_statements_to_distribute(statement module_stat)
This function return a list of statements that are marked for externalization.

References identify_statements_to_distribute().

Referenced by phrase_distributor_init().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ remove_begin_tag()

static void remove_begin_tag ( statement  stat,
string  function_name 
)
static

Remove begin tag for statement stat and function function_name.

Definition at line 127 of file phrase_distributor.c.

128 {
129  char* removed_tag ;
130  asprintf (&removed_tag,EXTERNALIZED_CODE_PRAGMA_BEGIN,function_name);
131  ifdebug(2) {
132  pips_debug(2, "REMOVE %s from\n", removed_tag);
133  print_statement (stat);
134  }
135  clean_statement_from_tags (removed_tag, stat);
136 }
void clean_statement_from_tags(const char *, statement)
Definition: phrase_tools.c:414

References asprintf, clean_statement_from_tags(), EXTERNALIZED_CODE_PRAGMA_BEGIN, ifdebug, pips_debug, and print_statement().

Referenced by isolate_code_portion().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ remove_end_tag()

static void remove_end_tag ( statement  stat,
string  function_name 
)
static

Remove end tag for statement stat and function function_name.

Definition at line 141 of file phrase_distributor.c.

142 {
143  char* removed_tag ;
144  asprintf (&removed_tag,EXTERNALIZED_CODE_PRAGMA_END,function_name);
145  ifdebug(2) {
146  pips_debug(2, "REMOVE %s from\n", removed_tag);
147  print_statement (stat);
148  }
149  clean_statement_from_tags (removed_tag, stat);
150 }

References asprintf, clean_statement_from_tags(), EXTERNALIZED_CODE_PRAGMA_END, ifdebug, pips_debug, and print_statement().

Referenced by isolate_code_portion().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ dynamic_area