24 #include "pips_config.h"
69 user_log(
"Statistics about cleaning up sequences:\n");
71 user_log(
"\t%d empty sequence%s or useless CONTINUE removed.\n",
79 user_log(
"\t%d sequence%s of only 1 statement have been removed.\n",
159 pips_debug(1,
"%s merge sequences with declarations\n",
227 pips_debug(7,
"Adding GOTO from instruction %p to statement %p.\n",
259 pips_assert(
"Map statement_to_goto_table should be uninitialized.\n",
296 pips_debug(6,
"Adjusting GOTO from instruction %p -> statement %p to "
307 if (*the_comments != NULL) {
311 *the_comments = NULL;
325 bool changed =
false;
332 while (!
ENDP(l_decl))
363 list useful_sts, delete_sts;
364 string the_comments = NULL;
366 useful_sts = delete_sts =
NIL;
373 "Number=%d, label=\"%s\", comment=\"%s\"\n",
379 " and commentless.\n");
389 pips_debug(3,
"A sequence of %zd statements with %zd declarations\n",
400 fprintf(stderr,
"[ Empty statement or continue ]\n");
404 if (the_comments == NULL)
411 string new_comments =
414 the_comments = new_comments;
430 pips_debug(4,
"l_internal_proper_decls = \n");
433 pips_debug(4,
"internal statement declarations");
443 if (
ENDP(l_stmt_to_be_merged)) {
468 !
ENDP(l_internal_proper_decls))
479 bool parent_decl_with_same_name =
false;
483 if (parent_decl != decl
486 parent_decl_with_same_name =
true;
494 string decl_without_module_and_scope = strrchr(decl_name,
BLOCK_SEP_CHAR);
498 pips_debug(6,
"decl name without module+scope: %s\n", decl_without_module_and_scope);
500 if (decl_without_module_and_scope == NULL)
504 pips_debug(6,
"non consistant variable scope\n");
505 if (top_level_entity_with_same_name_p)
508 else if (decl_without_module_and_scope[-1]==
'0' &&
511 pips_debug(6,
"Entity already at the uppermost scope level\n");
512 if (top_level_entity_with_same_name_p)
528 module_and_new_scope =
strndup(decl_name, decl_without_module_and_scope-decl_name-i+1);
530 pips_debug(6,
"module+scope of new decl: %s\n", module_and_new_scope);
532 free(module_and_new_scope);
534 pips_debug(6,
"new decl name: %s\n", new_name);
536 if (parent_decl_with_same_name ||
537 top_level_entity_with_same_name_p )
552 hash_put(renamings, decl, new_decl);
553 l_new_decls =
CONS(
ENTITY, new_decl, l_new_decls);
583 useful_sts =
gen_nconc(useful_sts, l_stmt_to_be_merged);
585 pips_debug(3,
"2 nested sequences fused...\n");
600 if (the_comments != NULL) p_ctxt->
changed =
true;
611 if (the_comments != NULL ) {
618 pips_debug(3,
"CONTINUE created to add a pending comment...\n");
666 pips_debug(3,
"Sequence with 1 statement replaced by 1 statement...\n");
678 debug_on(
"CLEAN_UP_SEQUENCES_DEBUG_LEVEL");
707 debug_on(
"CLEAN_UP_SEQUENCES_DEBUG_LEVEL");
void user_log(const char *format,...)
value make_value_unknown(void)
bool statement_consistent_p(statement p)
void free_instruction(instruction p)
static reference ref
Current stmt (an integer)
static bool store_declarations_references(statement st, cusq_context *p_ctxt)
bool clean_up_sequences_internal(statement s)
An entry point for internal usage, such as from take_out_the_exit_node_if_not_a_continue():
static void clean_up_sequences_rewrite(statement s, cusq_context *p_ctxt)
hash_table statement_to_goto_table
clean_up_sequences.c
void initialize_clean_up_sequences_statistics(void)
void compute_statement_to_goto_table(statement s)
Since clean_up_sequences() is called before the controlizer, there may be some GOTO.
static void deal_with_pending_comment(statement s, string *the_comments)
void discard_statement_to_goto_table(void)
Discard the statement_to_goto_table map:
static void cusq_ctxt_reset(cusq_context *p_ctxt)
static bool store_reference(reference ref, cusq_context *p_ctxt)
static int clean_up_fused_sequences
static bool sequence_proper_declarations_rename_in_place(sequence seq, hash_table renamings)
change the declarations of declaration statements directly contained in input sequence according to t...
void adjust_goto_from_to(statement s1, statement s2)
Adjust all the GOTOs pointing s1 to s2:
bool clean_up_sequences(statement s)
Recursively clean up the statement sequences by fusing them if possible and by removing useless one.
static void replace_entities_in_cusq_context(cusq_context *p_ctxt, hash_table ht)
replace entities in the module references and loop indices and loop locals stored in the input cusq_c...
void display_clean_up_sequences_statistics(void)
bool statement_to_goto_table_flt(instruction i)
End: clean up sequences context.
static bool store_loops(loop l, cusq_context *p_ctxt)
static int clean_up_1_statement_sequence
static int clean_up_empty_block_removed
Clean up the sequences and their contents by fusing them or removing useless continues or empty instr...
static void cusq_ctxt_init(statement s, cusq_context *p_ctxt)
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
#define gen_recurse(start, domain_number, flt, rwt)
union gen_chunk * gen_chunkp
void gen_full_free_list(list l)
entity get_current_module_entity(void)
Get the entity of the current module.
void gen_context_multi_recurse(void *o, void *context,...)
Multi-recursion with context function visitor.
void gen_null2(__attribute__((unused)) void *u1, __attribute__((unused)) void *u2)
idem with 2 args, to please overpeaky compiler checks
bool gen_true2(__attribute__((unused)) gen_chunk *u1, __attribute__((unused)) void *u2)
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
#define ENDP(l)
Test if a list is empty.
void gen_remove(list *cpp, const void *o)
remove all occurences of item o from list *cpp, which is thus modified.
#define POP(l)
Modify a list pointer to point on the next element of the list.
#define NIL
The empty list (nil in Lisp)
size_t gen_length(const list l)
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
#define CAR(pcons)
Get the value of the first element of a list.
void gen_free_list(list l)
free the spine of the list
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
sequence statement_sequence(statement)
Get the sequence of a statement sequence.
bool empty_statement_or_labelless_continue_p(statement)
Return true if the statement is an empty instruction block without label or a continue without label ...
bool unlabelled_statement_p(statement)
bool empty_statement_p(statement)
Test if a statement is empty.
bool statement_sequence_p(statement)
Statement classes induced from instruction type.
void insert_comments_to_statement(statement, const char *)
Insert a comment string (if non empty) at the beginning of the comments of a statement.
string statement_identification(statement)
Like external_statement_identification(), but with internal information, the hexadecimal address of t...
list statement_to_declarations(void *)
Get a list of all variables declared recursively within a statement.
list statement_to_direct_declarations(statement)
Returns the declarations contained directly in a statement s.
bool empty_comments_p(const char *)
bool statement_with_empty_comment_p(statement)
Return true if the statement has an empty statement:
statement make_plain_continue_statement(void)
Make a simple continue statement to be used as a NOP or ";" in C.
bool declaration_statement_p(statement)
Had to be optimized according to Beatrice Creusillet.
hash_table hash_table_make(hash_key_type key_type, size_t size)
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.
void hash_put(hash_table htp, const void *key, const void *val)
This functions stores a couple (key,val) in the hash table pointed to by htp.
void hash_update(hash_table htp, const void *key, const void *val)
update key->val in htp, that MUST be pre-existent.
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
bool hash_defined_p(const hash_table htp, const void *key)
true if key has e value in htp.
void * hash_del(hash_table htp, const void *key)
this function removes from the hash table pointed to by htp the couple whose key is equal to key.
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
#define pips_internal_error
#define TOP_LEVEL_MODULE_NAME
Module containing the global variables in Fortran and C.
#define MODULE_SEP_STRING
string concatenate(const char *,...)
Return the concatenation of the given strings.
#define HASH_MAP(k, v, code, ht)
#define HASH_UNDEFINED_VALUE
value returned by hash_get() when the key is not found; could also be called HASH_KEY_NOT_FOUND,...
#define HASH_DEFAULT_SIZE
#define STATEMENT_NUMBER_UNDEFINED
default values
#define entity_declarations(e)
MISC: newgen shorthands.
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
entity FindEntity(const char *package, const char *name)
Retrieve an entity from its package/module name and its local name.
entity make_entity_copy_with_new_name_and_suffix(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...
void print_entities(list l)
const char * label_local_name(entity e)
END_EOLE.
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...
void AddLocalEntityToDeclarationsOnly(entity, entity, statement)
Add the variable entity e to the list of variables of the function module.
#define extensions_undefined
#define value_undefined_p(x)
#define REFERENCE(x)
REFERENCE.
#define instruction_sequence_p(x)
#define reference_variable(x)
#define loop_domain
newgen_language_domain_defined
#define INSTRUCTION(x)
INSTRUCTION.
#define instruction_goto(x)
#define statement_domain
newgen_sizeofexpression_domain_defined
#define instruction_domain
newgen_functional_domain_defined
#define instruction_undefined
#define statement_label(x)
#define entity_undefined_p(x)
#define reference_domain
newgen_range_domain_defined
#define sequence_statements(x)
#define statement_extensions(x)
#define instruction_sequence(x)
#define statement_declarations(x)
#define statement_instruction(x)
#define statement_comments(x)
#define extensions_extension(x)
#define statement_number(x)
#define instruction_goto_p(x)
#define STATEMENT(x)
STATEMENT.
#define entity_initial(x)
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strndup(char const *s, size_t n)
A replacement function, for systems that lack strndup.
The structure used to build lists in NewGen.
Clean up sequences context.
bool merge_sequences_with_declarations