PIPS
flatten_code.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include "genC.h"
#include "linear.h"
#include "misc.h"
#include "properties.h"
#include "pipsdbm.h"
#include "ri.h"
#include "ri-util.h"
#include "prettyprint.h"
#include "control.h"
#include "transformations.h"
+ Include dependency graph for flatten_code.c:

Go to the source code of this file.

Data Structures

struct  redeclaration_context
 To generate the new variables, we need to know: More...
 

Typedefs

typedef struct redeclaration_context redeclaration_context_t
 To generate the new variables, we need to know: More...
 

Functions

static void rename_reference (reference r, hash_table renamings)
 Flatten code. More...
 
static void rename_loop_index (loop l, hash_table renamings)
 gen_multi_recurse callback on exiting a loop: if loop index needs renaming, rename this occurrence. More...
 
static void rename_variable_type (entity var, hash_table renamings)
 If the type of variable var is a typedefed type, it may have been renamed and the symbol table must be updated. More...
 
static void rename_statement_declarations (statement s, hash_table renamings)
 gen_multi_recurse callback on exiting a statement: recompute the declaration list for statement s and transform initializations into assignments when required according to the renaming map "renamings". More...
 
static bool redeclaration_enter_statement (statement s, redeclaration_context_t *rdcp)
 This function makes the key decision about the renaming: should the variable be renamed? Are the renaming and declaration move compatible with its initialization expression and its control context? More...
 
static void redeclaration_exit_statement (statement s, redeclaration_context_t *rdcp)
 Keep track of cycle exit in the hierarchical control flow graph. More...
 
static void compute_renamings (statement s, const char *sc, const char *mn, hash_table renamings)
 FI: added to wrap up the use of redeclaration context... More...
 
bool statement_flatten_declarations (entity module, statement s)
 flatten_code.c More...
 
static void unroll_loops_in_statement (statement s)
 
static void statement_purge_declarations_walker (sequence seq)
 
static void statement_purge_declarations (statement s)
 
bool flatten_code (const string module_name)
 Pipsmake 'flatten_code' phase. More...
 
void statement_split_initializations (statement s)
 Recurse through the statements of s and split local declarations. More...
 
bool split_initializations (const char *module_name)
 Pipsmake 'split_initializations' phase. More...
 
void split_update_call (call c)
 
static void split_update_operator_statement_walker (statement s)
 
bool split_update_operator (const char *module_name)
 

Typedef Documentation

◆ redeclaration_context_t

To generate the new variables, we need to know:

  • if there is an enclosing control cycle
  • what is the (current) statement to be used for declaration
  • the current scope corresponding to that statement
  • the current module name (get_current_module_name() could be used instead)
  • and the renaming map

This data structure is private to flatten_code.c

Function Documentation

◆ compute_renamings()

static void compute_renamings ( statement  s,
const char *  sc,
const char *  mn,
hash_table  renamings 
)
static

FI: added to wrap up the use of redeclaration context...

Definition at line 461 of file flatten_code.c.

463 {
464  string mnc = strdup(mn);
465  redeclaration_context_t rdc = { 0, s, sc, mnc, renamings};
466 
468  &rdc,
472 
473  free(mnc);
474 }
static void redeclaration_exit_statement(statement s, redeclaration_context_t *rdcp)
Keep track of cycle exit in the hierarchical control flow graph.
Definition: flatten_code.c:447
static bool redeclaration_enter_statement(statement s, redeclaration_context_t *rdcp)
This function makes the key decision about the renaming: should the variable be renamed?...
Definition: flatten_code.c:275
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
Definition: genC.h:285
void free(void *)
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define statement_instruction(x)
Definition: ri.h:2458
char * strdup()
To generate the new variables, we need to know:
Definition: flatten_code.c:263

References free(), gen_context_recurse, redeclaration_enter_statement(), redeclaration_exit_statement(), statement_domain, statement_instruction, and strdup().

Referenced by statement_flatten_declarations().

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

◆ flatten_code()

bool flatten_code ( const string  module_name)

Pipsmake 'flatten_code' phase.

This function is be composed of several steps:

1 flatten declarations inside statement: declarations are moved as high as possible in the control structure; this may serialize parallel loops, but this pass was designed for sequential code.

2 clean_up_sequences: remove useless braces when they are nested.

3 unroll looops with statically known iteration number.

4 clean_up_sequences: remove useless braces when they are nested.

It is assumed that the function main statement will contain at least one local variable. This is used to preserve the scoping mechanism used by the parser. Thus, "void foo(void){{{}}}" cannot be flatten. Note that clean_up_sequences could be used first to avoid such cases. Function "void foo(void){{{extern int i;}}}" cannot be flatten either, but clean_up_sequences might help.

Is it a top-level entity?

Parameters
module_nameodule_name

Definition at line 648 of file flatten_code.c.

649 {
650  bool good_result_p = true;
651 
655  code c = value_code(mv); // No check on value's kind
656  list dl = code_declarations(c);
657 
658  debug_on("FLATTEN_CODE_DEBUG_LEVEL");
659  pips_debug(1, "begin\n");
660 
661  // Step 0: the algorithms used do not deal with dependent or
662  // variable-length array (VLA) types unless they are formal parameters
663  // or appear at top-level... (see TRAC ticket 751)
664  // Declarations are moved to the top, without any regard to data dependencies
665  FOREACH(ENTITY, v, dl) {
666  if(!entity_formal_p(v)) {
667  type t = entity_type(v);
668  if(dependent_type_p(t)) {
669  string eln = (string) entity_local_name(v);
670  string s = local_name_to_scope(eln);
671  /* Is it a top-level entity? */
672  if(strlen(s)>2) {
673  good_result_p = false;
674  break;
675  }
676  else {
677  pips_user_warning("Code generated by pass Flatten_code may be wrong"
678  " because of VLA type of variable \"%s\"\n",
679  entity_user_name(v));
680  }
681  }
682  }
683  }
684 
685  if(!good_result_p) {
686  pips_user_warning("Module \"%s\" could not be flattened because it uses a variable-length array (VLA).\n", entity_user_name(module));
687  }
688  else {
690  db_get_memory_resource(DBR_CODE, module_name, true) );
691  statement module_stat = get_current_module_statement();
692 
693  // Step 1 and 2: flatten declarations and clean up sequences
694  if ((good_result_p=statement_flatten_declarations(module,module_stat)))
695  {
696  statement_purge_declarations(module_stat);
697  // call sequence flattening as some declarations may have been moved up
698  clean_up_sequences(module_stat);
699 
700  // Step 3 and 4: unroll loops and clean up sequences
701  if(get_bool_property("FLATTEN_CODE_UNROLL"))
702  {
703  gen_recurse(module_stat,
705  clean_up_sequences(module_stat); // again
706  }
707 
708  // This might not be necessary, thanks to clean_up_sequences
709  module_reorder(module_stat);
710  // Save modified code to database
711  DB_PUT_MEMORY_RESOURCE(DBR_CODE, strdup(module_name), module_stat);
712  }
714  }
715 
716  pips_debug(1, "end\n");
717  debug_off();
718 
720 
721  return good_result_p;
722 }
bool clean_up_sequences(statement s)
Recursively clean up the statement sequences by fusing them if possible and by removing useless one.
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
bool statement_flatten_declarations(entity module, statement s)
flatten_code.c
Definition: flatten_code.c:509
static void statement_purge_declarations(statement s)
Definition: flatten_code.c:620
static void unroll_loops_in_statement(statement s)
Definition: flatten_code.c:591
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
#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
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 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 debug_off()
Definition: misc-local.h:160
char * string
STRING.
Definition: newgen_types.h:39
static char * module
Definition: pips.c:74
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
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_formal_p(entity p)
is p a formal parameter?
Definition: entity.c:1935
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
string local_name_to_scope(const char *ln)
allocates a new string
Definition: entity.c:563
bool dependent_type_p(type)
A type is dependent in many ways according to definitions given in Wikipedia.
Definition: type.c:5849
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define code_declarations(x)
Definition: ri.h:784
#define value_code(x)
Definition: ri.h:3067
#define entity_type(x)
Definition: ri.h:2792
#define entity_initial(x)
Definition: ri.h:2796
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References clean_up_sequences(), code_declarations, db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, dependent_type_p(), ENTITY, entity_formal_p(), entity_initial, entity_local_name(), entity_type, entity_user_name(), FOREACH, gen_recurse, gen_true(), get_bool_property(), get_current_module_entity(), get_current_module_statement(), local_name_to_scope(), module, module_name(), module_name_to_entity(), module_reorder(), pips_debug, pips_user_warning, reset_current_module_entity(), reset_current_module_statement(), set_current_module_entity(), set_current_module_statement(), statement_domain, statement_flatten_declarations(), statement_purge_declarations(), strdup(), unroll_loops_in_statement(), and value_code.

+ Here is the call graph for this function:

◆ redeclaration_enter_statement()

static bool redeclaration_enter_statement ( statement  s,
redeclaration_context_t rdcp 
)
static

This function makes the key decision about the renaming: should the variable be renamed? Are the renaming and declaration move compatible with its initialization expression and its control context?

Are we entering a (potential) cycle? Do we have a function to detect unstructured with no cycles?

This is not a local variable. Its declaration can be moved if not already there.

This is a block local stack allocated or static variable or a derived type or a typedef type

FI: the case of static variables is not taken into account properly.

Can we move or transform the initialization?

No initialization issue, let's move the declaration

We are in a control cycle. The initial value must be reassigned where the declaration was, if the variable is not static.

It could be redeclared if a small function was synthesized to perform the assignment dynamically. Basically, a loop nest over the array dimensions.

We are not in a control cycle. The initial value expression, if constant, can be moved with the new declaration. This avoids problem with non-assignable expressions such as brace expressions used in initializations at declaration.

Build the new variable

const char* eun = entity_user_name(v);

string negn = typedef_entity_p(v)?

strdup(concatenate(mn, MODULE_SEP_STRING, rdcp->scope,

TYPEDEF_PREFIX, eun, NULL))

:

strdup(concatenate(mn, MODULE_SEP_STRING, rdcp->scope, eun, NULL));

When renaming the variable, we must make sure that we are not creating a user name conflict at source-code level. For now we will keep regenerating nv and checking it against the list of all entities used in the statement, until no conflict remains.

FI: I do not undestand why we look for references instead of declarations... (02/11/2014)

We iterate over suffixes (_0, _1, _2, ...) and test if we generate a conflict

FI: what happens to external entities whose declarations is moved, but the name unchanged?

Definition at line 275 of file flatten_code.c.

276 {
278 
279  /* Are we entering a (potential) cycle? Do we have a function to
280  detect unstructured with no cycles? */
281  if(instruction_loop_p(i)
285  rdcp->cycle_depth++;
288  const char* mn = rdcp->module_name;
289  string vn = entity_name(v);
290  const char* vmn = module_name(vn);
291 
292  if (hash_defined_p(rdcp->renamings, v)) {
293  pips_debug(5, "Skipping the already processed variable \"%s\" \n",
294  entity_user_name(v));
295  continue;
296  }
297 
298  if(strcmp(mn, vmn)!=0) {
299  /* This is not a local variable. Its declaration can be
300  moved if not already there. */
301  statement ds = rdcp->declaration_statement;
302  list dv = statement_declarations(ds);
303 
304  if(!entity_is_argument_p(v, dv)) {
305  pips_debug(5, "Entity is not an argument\n");
307  }
308  hash_put_or_update(rdcp->renamings, v, v);
309  }
310  else { /* This is a block local stack allocated or static
311  variable or a derived type or a typedef type */
312  /* FI: the case of static variables is not taken into account
313  properly. */
315  bool redeclare_p = false;
316  bool move_initialization_p = false;
317 
318  /* Can we move or transform the initialization? */
320 
321  /* No initialization issue, let's move the declaration */
322  redeclare_p = true;
323  move_initialization_p = true;
324  }
325  else if(rdcp->cycle_depth>0) {
326  /* We are in a control cycle. The initial value must be
327  reassigned where the declaration was, if the variable is
328  not static. */
329  if(variable_static_p(v)) {
330  redeclare_p = true;
331  move_initialization_p = true;
332  }
333  else if(expression_is_C_rhs_p(ie)) { // This function is not yet precise enough
334  redeclare_p = true;
335  move_initialization_p = false;
336  }
337  else {
338  /* It could be redeclared if a small function was
339  synthesized to perform the assignment
340  dynamically. Basically, a loop nest over the array
341  dimensions. */
342  redeclare_p = false;
343  move_initialization_p = false;
344  }
345  }
346  else {
347  /* We are not in a control cycle. The initial value
348  expression, if constant, can be moved with the
349  new declaration. This avoids problem with non-assignable
350  expressions such as brace expressions used in
351  initializations at declaration. */
353  redeclare_p = true;
354  move_initialization_p = true;
355  }
356  else if(expression_is_C_rhs_p(ie)) {
357  redeclare_p = true;
358  move_initialization_p = false;
359  }
360  else {
361  redeclare_p = false;
362  move_initialization_p = false;
363  }
364  }
365 
366  if(redeclare_p) {
367 
368  /* Build the new variable */
369  /* const char* eun = entity_user_name(v); */
370  /* string negn = typedef_entity_p(v)? */
371  /* strdup(concatenate(mn, MODULE_SEP_STRING, rdcp->scope, */
372  /* TYPEDEF_PREFIX, eun, NULL)) */
373  /* : */
374  /* strdup(concatenate(mn, MODULE_SEP_STRING, rdcp->scope, eun, NULL)); */
375  // const char* eun = entity_name_without_scope(v);
376  const char* eun = strrchr(entity_name(v), BLOCK_SEP_CHAR);
377  if(eun==NULL)
378  eun = strrchr(entity_name(v), MODULE_SEP_CHAR);
379  string negn =
380  strdup(concatenate(mn, MODULE_SEP_STRING, rdcp->scope, eun+1, NULL));
382  //list unused_nvs = NIL;
383 
384  /* When renaming the variable, we must make sure that we are
385  not creating a user name conflict at source-code
386  level. For now we will keep regenerating nv and checking
387  it against the list of all entities used in the
388  statement, until no conflict remains.
389  */
390 
391  statement ds = rdcp->declaration_statement;
392  /* FI: I do not undestand why we look for references instead
393  of declarations... (02/11/2014) */
395  bool is_same_name = false;
396 
397  ifdebug(8) {
398  pips_debug(8, "Entities found in declaration statement: ");
399  print_entities(dselist);
400  fprintf(stderr, "\n");
401  }
402 
403  /* We iterate over suffixes (_0, _1, _2, ...) and test if we
404  generate a conflict */
405  do {
406  nv = make_entity_copy_with_new_name(v, negn, move_initialization_p);
407  FOREACH(ENTITY, dv, dselist) {
408 
409  if (dv == v)
410  {
411  pips_debug(8, "Skipping the variable \"%s\" we are working on\n",
412  entity_user_name(v));
413  continue;
414  }
415 
416  is_same_name =
417  strcmp(entity_user_name(dv), entity_user_name(nv)) == 0;
418  if (is_same_name) {
419  pips_debug(1, "Proposed variable \"%s\" "
420  "conflicts with references in declaration statement\n",
421  entity_name(nv));
422  break;
423  }
424  }
425  if (is_same_name) {
426  // WARNING: We must remember to free the newly declared nv when it's not used!
427  //unused_nvs = CONS(ENTITY, nv, unused_nvs);
428  }
429  } while (is_same_name);
430 
431  /* FI: what happens to external entities whose declarations
432  is moved, but the name unchanged? */
435  rdcp->declaration_statement);
436  hash_put_or_update(rdcp->renamings, v, nv);
437  pips_debug(1, "Variable %s renamed as %s\n", entity_name(v), entity_name(nv));
438  }
439  }
440  }
441  }
442 
443  return true;
444 }
bool entity_is_argument_p(entity e, cons *args)
Definition: arguments.c:150
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
list statement_to_referenced_entities(statement)
Get a list of all variables referenced recursively within a statement:
Definition: statement.c:3428
bool hash_defined_p(const hash_table htp, const void *key)
true if key has e value in htp.
Definition: hash.c:484
#define BLOCK_SEP_CHAR
Definition: naming-local.h:51
#define MODULE_SEP_CHAR
Definition: naming-local.h:28
#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_put_or_update(h, k, v)
Definition: newgen_hash.h:80
void print_entities(list l)
Definition: entity.c:167
entity make_entity_copy_with_new_name(entity e, string global_new_name, bool move_initialization_p)
Create a copy of an entity, with (almost) identical type, storage and initial value if move_initializ...
Definition: entity.c:2463
bool expression_is_C_rhs_p(expression exp)
Not all expressions can be used as right-hand side (rhs) in C assignments.
Definition: expression.c:2582
bool extended_expression_constant_p(expression exp)
Returns true if the value of the expression does not depend syntactically on the current store.
Definition: expression.c:2461
bool entity_static_variable_p(entity)
return true if the entity is declared with the keyword static
Definition: variable.c:1146
void AddLocalEntityToDeclarations(entity, entity, statement)
Add the variable entity e to the list of variables of the function module.
Definition: variable.c:233
expression variable_initial_expression(entity)
Returns a copy of the initial (i.e.
Definition: variable.c:1899
bool variable_static_p(entity)
true if v appears in a SAVE statement, or in a DATA statement, or is declared static i C.
Definition: variable.c:1579
#define instruction_sequence_p(x)
Definition: ri.h:1512
#define instruction_loop_p(x)
Definition: ri.h:1518
#define instruction_forloop_p(x)
Definition: ri.h:1536
#define entity_undefined
Definition: ri.h:2761
#define entity_name(x)
Definition: ri.h:2790
#define instruction_unstructured_p(x)
Definition: ri.h:1530
#define expression_undefined_p(x)
Definition: ri.h:1224
#define statement_declarations(x)
Definition: ri.h:2460
#define instruction_whileloop_p(x)
Definition: ri.h:1521
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
#define ifdebug(n)
Definition: sg.c:47
const char * module_name
Definition: flatten_code.c:267
statement declaration_statement
Definition: flatten_code.c:265

References AddLocalEntityToDeclarations(), BLOCK_SEP_CHAR, concatenate(), redeclaration_context::cycle_depth, redeclaration_context::declaration_statement, ENDP, ENTITY, entity_is_argument_p(), entity_name, entity_static_variable_p(), entity_undefined, entity_user_name(), expression_is_C_rhs_p(), expression_undefined_p, extended_expression_constant_p(), FOREACH, fprintf(), get_current_module_entity(), hash_defined_p(), hash_put_or_update, ifdebug, instruction_forloop_p, instruction_loop_p, instruction_sequence_p, instruction_unstructured_p, instruction_whileloop_p, make_entity_copy_with_new_name(), module_name(), redeclaration_context::module_name, MODULE_SEP_CHAR, MODULE_SEP_STRING, pips_debug, print_entities(), redeclaration_context::renamings, redeclaration_context::scope, statement_declarations, statement_instruction, statement_to_referenced_entities(), strdup(), variable_initial_expression(), and variable_static_p().

Referenced by compute_renamings().

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

◆ redeclaration_exit_statement()

static void redeclaration_exit_statement ( statement  s,
redeclaration_context_t rdcp 
)
static

Keep track of cycle exit in the hierarchical control flow graph.

Are entering a (potential) cycle?

Definition at line 447 of file flatten_code.c.

449 {
451 
452  /* Are entering a (potential) cycle? */
453  if(instruction_loop_p(i)
457  rdcp->cycle_depth--;
458 }

References redeclaration_context::cycle_depth, instruction_forloop_p, instruction_loop_p, instruction_unstructured_p, instruction_whileloop_p, and statement_instruction.

Referenced by compute_renamings().

+ Here is the caller graph for this function:

◆ rename_loop_index()

static void rename_loop_index ( loop  l,
hash_table  renamings 
)
static

gen_multi_recurse callback on exiting a loop: if loop index needs renaming, rename this occurrence.

Take advantage of this opportunity to serialize the loop in order to avoid any inconsistency. Local variables moved out of the loop may require a privatization after flattening of the loop is to be kept parallel.

Definition at line 90 of file flatten_code.c.

91 {
92  entity var = loop_index(l);
93 
94  execution ex = loop_execution(l);
95  if(execution_parallel_p(ex))
97 
98  if (hash_defined_p(renamings, var)) {
99  entity nvar = (entity)hash_get(renamings, var);
100  if(nvar!=var) {
101  pips_debug(1, "Loop index %s renamed as %s\n",
103  loop_index(l) = nvar;
104  }
105  }
106 }
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
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
#define execution_tag(x)
Definition: ri.h:1207
#define loop_execution(x)
Definition: ri.h:1648
@ is_execution_sequential
Definition: ri.h:1189
#define execution_parallel_p(x)
Definition: ri.h:1211
#define loop_index(x)
Definition: ri.h:1640

References entity_local_name(), execution_parallel_p, execution_tag, hash_defined_p(), hash_get(), is_execution_sequential, loop_execution, loop_index, and pips_debug.

Referenced by statement_flatten_declarations().

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

◆ rename_reference()

static void rename_reference ( reference  r,
hash_table  renamings 
)
static

Flatten code.

Francois Irigoin, Fabien Coelho, Laurent Daverio. gen_multi_recurse callback on exiting a variable reference: if var needs renaming, rename this reference.

we need to unormalize the uppermost parent of this expression otherwise its normalized field gets incorrect

otherwise field normalized get wrong

Definition at line 55 of file flatten_code.c.

56 {
57  entity var = reference_variable(r);
58  bool replaced = false; // Keep track of any replacement
59  if (hash_defined_p(renamings, var)) {
60  entity nvar = (entity)hash_get(renamings, var);
61  if(nvar!=var) {
62  pips_debug(1, "Reference %s renamed as %s\n",
64  reference_variable(r) = nvar;
65  replaced = true;
66  }
67  }
68 
69  if(replaced) {
70  /* we need to unormalize the uppermost parent of this expression
71  * otherwise its normalized field gets incorrect */
72  expression next=(expression)r,parent = NULL;
73  while((next=(expression) gen_get_ancestor(expression_domain,next))) {
74  parent=next;
75  }
76  if(parent) {
77  unnormalize_expression(parent); /* otherwise field normalized get wrong */
78  }
79  }
80 }
struct _newgen_struct_expression_ * expression
Definition: alias_private.h:21
gen_chunk * gen_get_ancestor(int, const void *)
return the first ancestor object found of the given type.
Definition: genClib.c:3560
void unnormalize_expression(void *st)
void unnormalize_expression(expression exp): puts all the normalized field of expressions in "st" to ...
Definition: normalize.c:452
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154
#define reference_variable(x)
Definition: ri.h:2326

References entity_local_name(), expression_domain, gen_get_ancestor(), hash_defined_p(), hash_get(), pips_debug, reference_variable, and unnormalize_expression().

Referenced by rename_statement_declarations(), and statement_flatten_declarations().

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

◆ rename_statement_declarations()

static void rename_statement_declarations ( statement  s,
hash_table  renamings 
)
static

gen_multi_recurse callback on exiting a statement: recompute the declaration list for statement s and transform initializations into assignments when required according to the renaming map "renamings".

Renaming may be neutral to handle external variables. The initial values are used to specify if an assignment must be created or not.

holds the entity to remove from declarations

Well, we could synthesize a new function to perform the initialization.

If the new variable declaration does not contain the initial value of the variable declaration, an initialization statement must be inserted

FI: The comment below used to be true before we used declaration statements...

Do nothing and the local declaration will be lost

Should we worry that the type itself has been renamed because a typedef is used?

calling RemoveLocalEntityFromDeclarations will tidy the declarations and the declaration_statements

Insert the list of initialisation statements as a sequence at the beginning of s.

C99

FI: why kill he initial statement number?

FI: should be a call to defined_empty_comments() or something like it. Currently, empty_comments is a macro and its value is string_undefined:-(

Definition at line 137 of file flatten_code.c.

138 {
139  if (declaration_statement_p(s)) {
140  list inits = NIL;
141  list decls = statement_declarations(s); // Non-recursive
143  list ndecls = NIL;
144  list tmp = NIL; /* holds the entity to remove from declarations */
145 
146  pips_debug(1, "Begin for statement %p\n", s);
147 
148  FOREACH(ENTITY, var, decls) {
149  entity nvar = (entity)hash_get(renamings, var);
150 
151  if(entity_undefined_p(nvar)) {
152  /* Well, we could synthesize a new function to perform the
153  initialization. */
154  pips_debug(1, "Local variable %s is preserved because its initial value "
155  "is not assignable\n", entity_local_name(var));
156  ndecls = gen_nconc(ndecls, CONS(ENTITY, var, NIL));
157  replace_entities(entity_type(var),renamings);
158  }
159  else if(var!=nvar) {
160  /* If the new variable declaration does not contain the
161  initial value of the variable declaration, an
162  initialization statement must be inserted */
164  && value_unknown_p(entity_initial(nvar))) {
167  gen_context_recurse(ie,renamings,
169  replace_entities(entity_type(nvar),renamings);
170 
171  inits = gen_nconc(inits, CONS(statement, is, NIL));
172 
173  pips_debug(1, "Initialize var %s with initial value of var %s: ",
175  );
176  ifdebug(1){
177  print_expression(ie);
178  fprintf(stderr, "\n");
179  }
180  }
181  tmp=CONS(ENTITY,var,tmp);
182  }
183  else {
184  /* FI: The comment below used to be true before we used
185  declaration statements... */
186  /* Do nothing and the local declaration will be lost */
187  pips_debug(1, "Declaration for external variable \"%s\" moved.\n",
188  entity_name(var));
189  }
190  /* Should we worry that the type itself has been renamed because
191  a typedef is used? */
192  rename_variable_type(var, renamings);
193  }
194 
195  /* calling RemoveLocalEntityFromDeclarations will tidy the
196  declarations and the declaration_statements */
197  FOREACH(ENTITY,e,tmp)
199  gen_free_list(tmp);
200 
201  if(!ENDP(inits)) {
202  /* Insert the list of initialisation statements as a sequence at
203  the beginning of s.
204  */
205  inits = gen_nconc(inits,
207  ifdebug(1)
208  print_statements(inits);
209 #if 0
210  if(get_bool_property("C89_CODE_GENERATION")) {
211  /* The initializations must be inserted at the right place,
212  which may prove impossible if some of the initializations
213  cannot be moved but are used. Example:
214 
215  int a[] = {1, 2, 3};
216  int i = a[1];
217  */
218  pips_internal_error("C89 flattened code not generated yet");
219  }
220  else
221 #endif
222  { /* C99*/
225  /* FI: why kill he initial statement number? */
228  string c = statement_comments(s);
229  statement fs = STATEMENT(CAR(inits));
230  statement_comments(fs) = c;
231  /* FI: should be a call to defined_empty_comments() or
232  something like it. Currently, empty_comments is a macro
233  and its value is string_undefined:-( */
234  statement_comments(s) = strdup("");
235  }
236  }
237  }
238 
239  //gen_free_list(statement_declarations(s));
240 
241  statement_declarations(s) = ndecls;
242 
243  pips_debug(1, "End. Local declarations %s.\n",
244  ENDP(ndecls)? "removed" : "updated");
245  }
246 }
instruction make_instruction_sequence(sequence _field_)
Definition: ri.c:1169
sequence make_sequence(list a)
Definition: ri.c:2125
static void rename_variable_type(entity var, hash_table renamings)
If the type of variable var is a typedefed type, it may have been renamed and the symbol table must b...
Definition: flatten_code.c:110
static void rename_reference(reference r, hash_table renamings)
Flatten code.
Definition: flatten_code.c:55
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
Definition: statement.c:597
void replace_entities(void *s, hash_table ht)
Recursively substitute a set of entities in a statement.
Definition: replace.c:91
bool gen_true2(__attribute__((unused)) gen_chunk *u1, __attribute__((unused)) void *u2)
Definition: genClib.c:2785
#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
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
statement make_assign_statement(expression, expression)
Definition: statement.c:583
bool statement_with_empty_comment_p(statement)
Return true if the statement has an empty statement:
Definition: statement.c:126
bool declaration_statement_p(statement)
Had to be optimized according to Beatrice Creusillet.
Definition: statement.c:224
#define pips_internal_error
Definition: misc-local.h:149
void print_expression(expression e)
no file descriptor is passed to make is easier to use in a debugging stage.
Definition: expression.c:58
void print_statements(list)
Definition: statement.c:103
#define STATEMENT_NUMBER_UNDEFINED
default values
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
void RemoveLocalEntityFromDeclarations(entity, entity, statement)
Definition: variable.c:120
#define value_unknown_p(x)
Definition: ri.h:3077
#define entity_undefined_p(x)
Definition: ri.h:2762
#define reference_domain
newgen_range_domain_defined
Definition: ri.h:338
#define statement_comments(x)
Definition: ri.h:2456
#define statement_number(x)
Definition: ri.h:2452
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413

References CAR, CONS, declaration_statement_p(), ENDP, ENTITY, entity_initial, entity_local_name(), entity_name, entity_to_expression(), entity_type, entity_undefined_p, FOREACH, fprintf(), gen_context_recurse, gen_free_list(), gen_nconc(), gen_true2(), get_bool_property(), get_current_module_entity(), hash_get(), ifdebug, instruction_to_statement(), make_assign_statement(), make_instruction_sequence(), make_sequence(), NIL, pips_debug, pips_internal_error, print_expression(), print_statements(), reference_domain, RemoveLocalEntityFromDeclarations(), rename_reference(), rename_variable_type(), replace_entities(), STATEMENT, statement_comments, statement_declarations, statement_instruction, statement_number, STATEMENT_NUMBER_UNDEFINED, statement_with_empty_comment_p(), strdup(), value_unknown_p, and variable_initial_expression().

Referenced by statement_flatten_declarations().

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

◆ rename_variable_type()

static void rename_variable_type ( entity  var,
hash_table  renamings 
)
static

If the type of variable var is a typedefed type, it may have been renamed and the symbol table must be updated.

Definition at line 110 of file flatten_code.c.

111 {
112  type t = entity_type(var);
113  if(typedef_type_p(t)) {
114  variable v = type_variable(t);
115  basic b = variable_basic(v);
116  entity tt = basic_typedef(b);
117  entity ntt = (entity)hash_get(renamings, tt);
118  if(!entity_undefined_p(ntt))
119  basic_typedef(b) = ntt;
120  }
121  else if(struct_type_p(t) || union_type_p(t) || enum_type_p(t)){
122  variable v = type_variable(t);
123  basic b = variable_basic(v);
124  entity tt = basic_derived(b);
125  entity nst = (entity)hash_get(renamings, tt);
126  if(!entity_undefined_p(nst))
127  basic_typedef(b) = nst;
128  }
129 }
bool enum_type_p(type)
Returns true if t is of type derived and if the derived type is a enum.
Definition: type.c:3172
bool union_type_p(type)
Returns true if t is of type derived and if the derived type is a union.
Definition: type.c:3151
bool struct_type_p(type)
Returns true if t is of type derived and if the derived type is a struct.
Definition: type.c:3121
bool typedef_type_p(type)
Returns true if t is a typedefED type.
Definition: type.c:3189
#define basic_derived(x)
Definition: ri.h:640
#define type_variable(x)
Definition: ri.h:2949
#define basic_typedef(x)
Definition: ri.h:643
#define variable_basic(x)
Definition: ri.h:3120

References basic_derived, basic_typedef, entity_type, entity_undefined_p, enum_type_p(), hash_get(), struct_type_p(), type_variable, typedef_type_p(), union_type_p(), and variable_basic.

Referenced by rename_statement_declarations().

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

◆ split_initializations()

bool split_initializations ( const char *  module_name)

Pipsmake 'split_initializations' phase.

Save modified code to database

Parameters
module_nameodule_name

Definition at line 742 of file flatten_code.c.

743 {
744  statement module_stat;
745  bool good_result_p = true;
746 
749  db_get_memory_resource(DBR_CODE, module_name, true) );
750  module_stat = get_current_module_statement();
751 
752  debug_on("SPLIT_INITIALIZATIONS_DEBUG_LEVEL");
753  pips_debug(1, "begin\n");
754 
755  // Do split !
756  statement_split_initializations(module_stat);
757 
758  pips_debug(1, "end\n");
759  debug_off();
760 
761  /* Save modified code to database */
762  module_reorder(module_stat);
763  DB_PUT_MEMORY_RESOURCE(DBR_CODE, strdup(module_name), module_stat);
764 
767 
768  return (good_result_p);
769 }
void statement_split_initializations(statement s)
Recurse through the statements of s and split local declarations.
Definition: flatten_code.c:733

References db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, get_current_module_statement(), module_name(), module_name_to_entity(), module_reorder(), pips_debug, reset_current_module_entity(), reset_current_module_statement(), set_current_module_entity(), set_current_module_statement(), statement_split_initializations(), and strdup().

+ Here is the call graph for this function:

◆ split_update_call()

void split_update_call ( call  c)

Definition at line 772 of file flatten_code.c.

773 {
774  entity op = call_function(c);
775  list args = call_arguments(c);
777  if(!entity_undefined_p(new_op))
778  {
779  if(ENTITY_PLUS_C_P(new_op)||ENTITY_MINUS_C_P(new_op))
780  {
781  bool has_pointer =false;
783  {
785  if(basic_pointer_p(b)) { has_pointer=true;}
786  free_basic(b);
787  }
788  if(!has_pointer) {
791  }
792  }
793  ifdebug(1){
795  pips_debug(1,"changed expression \n");
796  print_expression(tmp);
798  free_expression(tmp);
799  }
800 
802  expression lhs = binary_call_lhs(c);
803  expression rhs = binary_call_rhs(c);
804  CAR(CDR(args)).p=(gen_chunkp)MakeBinaryCall(
805  new_op,
806  copy_expression(lhs),
807  rhs);
808 
809  ifdebug(1){
811  pips_debug(1,"into expression \n");
812  print_expression(tmp);
814  free_expression(tmp);
815  }
816  }
817 }
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
void free_expression(expression p)
Definition: ri.c:853
void free_basic(basic p)
Definition: ri.c:107
union gen_chunk * gen_chunkp
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define binary_call_rhs(c)
#define MINUS_OPERATOR_NAME
#define PLUS_OPERATOR_NAME
#define ENTITY_PLUS_C_P(e)
#define ENTITY_MINUS_C_P(e)
#define binary_call_lhs(c)
#define ASSIGN_OPERATOR_NAME
Definition: ri-util-local.h:95
entity update_operator_to_regular_operator(entity op)
Returns the binary operator associated to a C update operator such as +=.
Definition: entity.c:2154
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
expression call_to_expression(call c)
Build an expression that call a function or procedure.
Definition: expression.c:309
basic basic_of_expression(expression)
basic basic_of_expression(expression exp): Makes a basic of the same basic as the expression "exp".
Definition: type.c:1383
#define call_function(x)
Definition: ri.h:709
#define basic_pointer_p(x)
Definition: ri.h:635
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define syntax_call(x)
Definition: ri.h:2736
#define call_arguments(x)
Definition: ri.h:711
#define call_undefined
Definition: ri.h:685
#define expression_syntax(x)
Definition: ri.h:1247
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207

References ASSIGN_OPERATOR_NAME, basic_of_expression(), basic_pointer_p, binary_call_lhs, binary_call_rhs, call_arguments, call_function, call_to_expression(), call_undefined, CAR, CDR, copy_expression(), entity_intrinsic(), ENTITY_MINUS_C_P, ENTITY_PLUS_C_P, entity_undefined_p, exp, EXPRESSION, expression_syntax, FOREACH, free_basic(), free_expression(), ifdebug, MakeBinaryCall(), MINUS_OPERATOR_NAME, pips_debug, PLUS_OPERATOR_NAME, print_expression(), syntax_call, and update_operator_to_regular_operator().

Referenced by check_if_conv_call(), simd_supported_stat_p(), split_update_operator(), and split_update_operator_statement_walker().

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

◆ split_update_operator()

bool split_update_operator ( const char *  module_name)

Save modified code to database

Parameters
module_nameodule_name

Definition at line 834 of file flatten_code.c.

835 {
838  debug_on("SPLIT_UPDATE_OPERATOR_DEBUG_LEVEL");
839  pips_debug(1, "begin\n");
840 
844  NULL);
845 
846  pips_debug(1, "end\n");
847  debug_off();
848 
849  /* Save modified code to database */
851 
854  return true;
855 }
static void split_update_operator_statement_walker(statement s)
Definition: flatten_code.c:820
void split_update_call(call c)
Definition: flatten_code.c:772
void gen_multi_recurse(void *o,...)
Multi recursion visitor function.
Definition: genClib.c:3428
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58

References call_domain, db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, gen_multi_recurse(), gen_true(), get_current_module_statement(), module_name(), module_name_to_entity(), pips_debug, reset_current_module_entity(), reset_current_module_statement(), set_current_module_entity(), set_current_module_statement(), split_update_call(), split_update_operator_statement_walker(), and statement_domain.

+ Here is the call graph for this function:

◆ split_update_operator_statement_walker()

static void split_update_operator_statement_walker ( statement  s)
static

FI: this should be guarded by a declaration_statement_p(s), shouldn't it?

Definition at line 820 of file flatten_code.c.

821 {
822  /* FI: this should be guarded by a declaration_statement_p(s),
823  shouldn't it? */
824  if(declaration_statement_p(s)) {
826  {
827  value v = entity_initial(e);
828  if( !value_undefined_p(v) && value_expression_p( v ) )
830  }
831  }
832 }
#define value_undefined_p(x)
Definition: ri.h:3017
#define value_expression_p(x)
Definition: ri.h:3080

References call_domain, declaration_statement_p(), ENTITY, entity_initial, FOREACH, gen_recurse, gen_true(), split_update_call(), statement_declarations, value_expression_p, and value_undefined_p.

Referenced by split_update_operator().

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

◆ statement_flatten_declarations()

bool statement_flatten_declarations ( entity  module,
statement  s 
)

flatten_code.c

For the time being, we handle only blocks with declarations

Can we find out what the local scope of statement s is?

FI: Shouldn't it be "0`"?

current scope for se

Parameters
moduleodule

Definition at line 509 of file flatten_code.c.

510 {
511  /* For the time being, we handle only blocks with declarations */
512  if (statement_block_p(s)) {
514  // Recursive
516  bool renaming_p = false;
517  string cs = string_undefined;
518  int csl = INT_MAX;
519 
520  /* Can we find out what the local scope of statement s is? */
521  /* FI: Shouldn't it be "0`"? */
522  const char* cmn = entity_user_name(module);
524  string sen = entity_name(se);
525  const char* seln = entity_local_name(se);
526  string cs_se = local_name_to_scope(seln); /* current scope for se */
527  const char* mn = module_name(sen);
528 
529  if(same_string_p(mn, cmn)) {
530  renaming_p = true;
531  int cs_se_l = strlen(cs_se);
532  if(cs_se_l>0 && cs_se_l<csl) {
533  csl = cs_se_l;
534  cs = cs_se;
535  }
536  else {
537  free(cs_se);
538  }
539  }
540  else {
541  free(cs_se);
542  }
543  }
544  if (renaming_p) {
545  compute_renamings(s, cs, cmn, renamings);
546  // FC: 2014-12-20 kludge to avoid a coredump
547  if (cs != string_undefined) {
548  free(cs);
549  cs = string_undefined;
550  }
551  }
552 
553  if(renaming_p) {
554  ifdebug(1)
555  hash_table_fprintf(stderr,
556  // The warning will disappear when Fabien
557  // updates Newgen
558  //(char * (*)(void *)) entity_local_name,
559  //(char * (*)(void *)) entity_local_name,
562  renamings);
563 
564  //char *(*key_to_string)(void*),
565  //char *(*value_to_string)(void*),
566 
568  statement_instruction(s), renamings,
572  NULL);
573 
574  // This look like a bad hack, partially redundant with previous
575  // replacement but... only partially ! For instance extensions was not
576  // handled previously.
577  // Probably that there's need for factoring, but it'll be another time !
578  replace_entities(s,renamings);
579 
580  gen_free_list(declarations), declarations = NIL;
581  hash_table_free(renamings), renamings = NULL;
582  }
583  else {
584  pips_debug(2,"Code flattening fails because the statement does"
585  " not contain any local declaration\n");
586  }
587  }
588  return true;
589 }
static void rename_loop_index(loop l, hash_table renamings)
gen_multi_recurse callback on exiting a loop: if loop index needs renaming, rename this occurrence.
Definition: flatten_code.c:90
static void rename_statement_declarations(statement s, hash_table renamings)
gen_multi_recurse callback on exiting a statement: recompute the declaration list for statement s and...
Definition: flatten_code.c:137
static void compute_renamings(statement s, const char *sc, const char *mn, hash_table renamings)
FI: added to wrap up the use of redeclaration context...
Definition: flatten_code.c:461
void gen_context_multi_recurse(void *o, void *context,...)
Multi-recursion with context function visitor.
Definition: genClib.c:3373
list instruction_to_declarations(instruction)
Get a list of all variables declared recursively within an instruction.
Definition: statement.c:3279
void hash_table_fprintf(FILE *f, gen_string_func_t key_to_string, gen_string_func_t value_to_string, const hash_table htp)
This function prints the content of the hash_table pointed to by htp on file descriptor f,...
Definition: hash.c:548
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
@ hash_pointer
Definition: newgen_hash.h:32
#define HASH_DEFAULT_SIZE
Definition: newgen_hash.h:26
#define same_string_p(s1, s2)
string(* gen_string_func_t)(const void *)
Definition: newgen_types.h:111
#define string_undefined
Definition: newgen_types.h:40
#define statement_block_p(stat)
#define entity_declarations(e)
MISC: newgen shorthands.
#define loop_domain
newgen_language_domain_defined
Definition: ri.h:218
else
Definition: set.c:239

References compute_renamings(), ENTITY, entity_declarations, entity_local_name(), entity_name, entity_user_name(), FOREACH, free(), gen_context_multi_recurse(), gen_free_list(), gen_true(), HASH_DEFAULT_SIZE, hash_pointer, hash_table_fprintf(), hash_table_free(), hash_table_make(), ifdebug, instruction_to_declarations(), local_name_to_scope(), loop_domain, module, module_name(), NIL, pips_debug, reference_domain, rename_loop_index(), rename_reference(), rename_statement_declarations(), replace_entities(), same_string_p, statement_block_p, statement_domain, statement_instruction, and string_undefined.

Referenced by delay_communications(), delay_load_communications(), delay_store_communications(), and flatten_code().

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

◆ statement_purge_declarations()

static void statement_purge_declarations ( statement  s)
static

Definition at line 620 of file flatten_code.c.

621 {
623 }
static void statement_purge_declarations_walker(sequence seq)
Definition: flatten_code.c:601
#define sequence_domain
newgen_reference_domain_defined
Definition: ri.h:346

References gen_recurse, gen_true(), sequence_domain, and statement_purge_declarations_walker().

Referenced by flatten_code().

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

◆ statement_purge_declarations_walker()

static void statement_purge_declarations_walker ( sequence  seq)
static

Definition at line 601 of file flatten_code.c.

602 {
605 
606  FOREACH(ENTITY,e,decls)
607  {
608  bool decl_stat_found = false;
610  {
611  if(( decl_stat_found = ( declaration_statement_p(s) && !gen_chunk_undefined_p(gen_find_eq(e,statement_declarations(s))) ) ) )
612  break;
613  }
614  if(!decl_stat_found)
616  }
617  gen_free_list(decls);
618 }
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
#define gen_chunk_undefined_p(c)
Definition: genC.h:75
void gen_remove_once(list *pl, const void *o)
Remove the first occurence of o in list pl:
Definition: list.c:691
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
void * gen_find_eq(const void *item, const list seq)
Definition: list.c:422
#define sequence_statements(x)
Definition: ri.h:2360

References declaration_statement_p(), ENTITY, FOREACH, gen_chunk_undefined_p, gen_copy_seq(), gen_find_eq(), gen_free_list(), gen_get_ancestor(), gen_remove_once(), sequence_statements, STATEMENT, statement_declarations, and statement_domain.

Referenced by statement_purge_declarations().

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

◆ statement_split_initializations()

void statement_split_initializations ( statement  s)

Recurse through the statements of s and split local declarations.

For the time being, we handle only blocks with declarations.

NOTE: Statement s is modified in-place.

This function can be called from another module to apply transformation directly.

Is it still useful?

Definition at line 733 of file flatten_code.c.

734 {
736  /* Is it still useful? */
738 }
void split_initializations_in_statement(statement s)
Transform a declaration with an initialization statement into 2 parts, a declaration statement and an...
Definition: declarations.c:437

References clean_up_sequences(), gen_recurse, gen_true(), split_initializations_in_statement(), and statement_domain.

Referenced by process_true_stat(), promote_local_entities(), and split_initializations().

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

◆ unroll_loops_in_statement()

static void unroll_loops_in_statement ( statement  s)
static

Definition at line 591 of file flatten_code.c.

591  {
592 
593  if (statement_loop_p(s)) {
594  loop l = statement_loop(s);
595 
597  full_loop_unroll(s);
598  }
599 }
loop statement_loop(statement)
Get the loop of a statement.
Definition: statement.c:1374
bool statement_loop_p(statement)
Definition: statement.c:349
bool loop_fully_unrollable_p(loop l)
Definition: loop_unroll.c:753
void full_loop_unroll(statement loop_statement)
get rid of the loop by body replication;
Definition: loop_unroll.c:788

References full_loop_unroll(), loop_fully_unrollable_p(), statement_loop(), and statement_loop_p().

Referenced by flatten_code().

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