PIPS
|
#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"
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 struct redeclaration_context redeclaration_context_t |
To generate the new variables, we need to know:
This data structure is private to flatten_code.c
|
static |
FI: added to wrap up the use of redeclaration context...
Definition at line 461 of file flatten_code.c.
References free(), gen_context_recurse, redeclaration_enter_statement(), redeclaration_exit_statement(), statement_domain, statement_instruction, and strdup().
Referenced by statement_flatten_declarations().
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?
module_name | odule_name |
Definition at line 648 of file flatten_code.c.
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.
|
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.
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().
|
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.
References redeclaration_context::cycle_depth, instruction_forloop_p, instruction_loop_p, instruction_unstructured_p, instruction_whileloop_p, and statement_instruction.
Referenced by compute_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.
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().
|
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.
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().
|
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.
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().
|
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.
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().
bool split_initializations | ( | const char * | module_name | ) |
Pipsmake 'split_initializations' phase.
Save modified code to database
module_name | odule_name |
Definition at line 742 of file flatten_code.c.
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().
void split_update_call | ( | call | c | ) |
Definition at line 772 of file flatten_code.c.
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().
bool split_update_operator | ( | const char * | module_name | ) |
Save modified code to database
module_name | odule_name |
Definition at line 834 of file flatten_code.c.
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.
|
static |
FI: this should be guarded by a declaration_statement_p(s), shouldn't it?
Definition at line 820 of file flatten_code.c.
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().
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
module | odule |
Definition at line 509 of file flatten_code.c.
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().
|
static |
Definition at line 620 of file flatten_code.c.
References gen_recurse, gen_true(), sequence_domain, and statement_purge_declarations_walker().
Referenced by flatten_code().
|
static |
Definition at line 601 of file flatten_code.c.
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().
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.
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().
|
static |
Definition at line 591 of file flatten_code.c.
References full_loop_unroll(), loop_fully_unrollable_p(), statement_loop(), and statement_loop_p().
Referenced by flatten_code().