36 #include "pips_config.h"
112 #include "constants.h"
115 #define LABEL_TABLES_SIZE 10
253 hash_put(used_labels, name, new_sts);
256 pips_debug(5,
"Reference to statement %d seen\n",
304 while((cl=
hash_table_scan(used_labels, cl, (
void **) &name, (
void **) &stats))) {
327 pips_debug(5,
"does not cover label %s\n", (
char *) name);
336 fprintf(stderr,
"covers its label usage\n");
375 pips_debug(8,
"control %p allocated for label \"%s\"", c, name);
408 pips_debug(8,
"control %p allocated for label \"%s\"", c, name);
605 pips_debug(5,
"(st = %p, c_res = %p, succ = %p)\n", sl, c_res, succ);
650 pips_debug(6,
"Since we can keep the do-loop, remove the useless control node %p that was allocated for the loop_body.\n", c_body);
731 pips_debug(5,
"(st = %p, c_res = %p, succ = %p)\n", sl, c_res, succ);
775 pips_debug(6,
"Since we can keep the do-loop, remove the useless control node %p that was allocated for the loop_body.\n", c_body);
855 pips_debug(5,
"(st = %p, c_res = %p, succ = %p)\n", sl, c_res, succ);
903 pips_debug(6,
"Since we can keep the whileloop, remove the useless control node %p that was allocated for the loop_body.\n", c_body);
950 pips_assert(
"c_test is a test with two successors",
953 pips_assert(
"c_body may have two successors if it is a test",
998 pips_debug(5,
"(st = %p, c_res = %p, succ = %p)\n", sl, c_res, succ);
1042 pips_debug(6,
"Since we can keep the do-loop, remove the useless control node %p that was allocated for the loop_body.\n", c_body);
1090 pips_assert(
"c_test is a test with two successors",
1093 pips_assert(
"c_body may have two successors if it is a test",
1163 "with GO TO exit had to be desugared\n",
1171 " with GO TO exit had to be desugared\n",
1191 "with GO TO exit had to be desugared\n",
1199 " with GO TO exit had to be desugared\n",
1223 bool old_controlize_whileloop(st, l, pred, succ, c_res, used_labels)
1234 pips_debug(5,
"(st = %p, pred = %p, succ = %p, c_res = %p)\n",
1235 st, pred, succ, c_res);
1267 controlized =
false;
1278 controlized =
true ;
1365 bool controlized =
false;
1368 pips_debug(5,
"(st = %p, pred = %p, succ = %p, c_res = %p)\n",
1369 st, pred, succ, c_res);
1452 controlized =
false;
1474 controlized =
true ;
1509 statement s_above = scoping_statement_nth(2);
1514 pips_debug(2,
"Dealing with block statement %p included into block"
1515 " statement %p\n", s, s_above);
1517 if (s_above == NULL)
1533 pips_debug(2,
"Comparing variables %s and %s\n",
1536 if (strcmp(name, name_above) == 0) {
1642 pips_assert(
"c has one successor (but may be zero with"
1643 " dead code behind declarations:-(",
1673 while((ccp =
hash_table_scan(old_to_new_variables, ccp, (
void *) &old, (
void *) &
new))) {
1681 for(cl=dl; !
ENDP(cl);
POP(cl)) {
1757 bool found_p =
false;
1760 while(!
ENDP(to_be_visited)) {
1775 && s!=succ && s!=
exit)
1822 pips_assert(
"succ has only one successor or none",
1829 pips_debug(8,
"succ has a fitting predecessor as exit.\n");
1843 pips_debug(8,
"succ is unreachable and a new exit node %p is created.\n",
1875 pips_debug(8,
"succ is reachable thru %d control paths "
1876 "but a new exit node %p is created.\n",
1920 bool controlized =
false;
1925 pips_debug(5,
"Entering with nodes linked with c_res %p:\n", c_res);
1933 scoping_statement_push(st);
1951 bool must_be_controlized_p =
false;
1967 pips_debug(8,
"This control %p pre-existed. "
1968 "The sequence cannot be controlized.\n", c);
1969 must_be_controlized_p =
true;
1990 if(!must_be_controlized_p) {
1992 pips_assert(
"c may have only one successor even if it is a test "
2011 pips_debug(5,
"Controlize each statement sequence node in reverse order:\n");
2021 if (!controlized && !must_be_controlized_p) {
2026 pips_assert(
"c may have two successors only if it is a test",
2034 pips_assert(
"c may have two successors only if it is a test",
2047 pips_debug(5,
"Keep a statement sequence and thus remove"
2048 " previously allocated control nodes for the sequence.\n");
2056 pips_debug(6,
"Removing useless control node %p.\n", c);
2066 pips_assert(
"a test has two successors\n", nsucc==2);
2072 pips_assert(
"a non test has one successor at most\n", nsucc<=1);
2078 pips_debug(1,
"Abnormal control: not a test, two successors.\n");
2133 pips_debug(5,
"Create a local unstructured with entry node %p and exit node %p\n", entry,
exit);
2183 controlized =
false;
2188 pips_debug(5,
"There are goto to/from outside this statement list"
2189 " so keep control nodes without any hierarchy here.\n");
2209 if (!hierarchized_labels) {
2219 scoping_statement_pop();
2252 pips_debug(5,
"Entering (st = %p, c_res = %p, succ = %p)\n",
2301 pips_debug(5,
"Restructure the IF at control %p\n", c_res);
2314 controlized =
false;
2317 pips_debug(5,
"Destructure the IF at control %p\n", c_res);
2386 pips_debug(5,
"After freeing the goto, from c_res = %p:\n", c_res);
2389 pips_debug(5,
"From n_succ = %p:\n", n_succ);
2393 if (succ == n_succ) {
2404 " to statement %p in hash table Label_statements\n");
2406 controlized =
false;
2412 pips_debug(5,
"Unstructured goto to label %s: control n_succ %p\n"
2413 "\tSo statement in control %p is now unreachable from this way\n",
2414 name, n_succ, succ);
2425 pips_debug(5,
"After freeing the goto, from c_res = %p:\n", c_res);
2459 pips_debug(5,
"(st = %p, c_res = %p, succ = %p)\n",
2503 bool controlized =
false;
2507 "Begin with (st = %p, c_res = %p, succ = %p)\n"
2512 pips_debug(1,
"Control list from c_res %p:\n", c_res);
2564 pips_assert(
"We are really dealing with a for loop",
2573 controlized =
false;
2591 pips_debug(1,
"Resulting Control c_res %p at exit:\n", c_res);
2653 make_scoping_statement_stack();
2679 free_scoping_statement_stack();
float a2sf[2] __attribute__((aligned(16)))
USER generates a user error (i.e., non fatal) by printing the given MSG according to the FMT.
unstructured make_unstructured(control a1, control a2)
call make_call(entity a1, list a2)
instruction make_instruction_forloop(forloop _field_)
value make_value_unknown(void)
expression make_expression(syntax a1, normalized a2)
whileloop make_whileloop(expression a1, statement a2, entity a3, evaluation a4)
list gen_entity_cons(entity p, list l)
instruction make_instruction_expression(expression _field_)
control check_control(control p)
expression copy_expression(expression p)
EXPRESSION.
bool statement_consistent_p(statement p)
test make_test(expression a1, statement a2, statement a3)
statement make_statement(entity a1, intptr_t a2, intptr_t a3, string a4, instruction a5, list a6, string a7, extensions a8, synchronization a9)
instruction make_instruction_sequence(sequence _field_)
instruction make_instruction_test(test _field_)
void free_instruction(instruction p)
instruction make_instruction(enum instruction_utype tag, void *val)
bool control_consistent_p(control p)
syntax make_syntax(enum syntax_utype tag, void *val)
synchronization make_synchronization_none(void)
instruction make_instruction_unstructured(unstructured _field_)
extensions copy_extensions(extensions p)
EXTENSIONS.
control make_control(statement a1, list a2, list a3)
void free_statement(statement p)
forloop make_forloop(expression a1, expression a2, expression a3, statement a4)
struct _newgen_struct_entity_ * entity
void const char const char const int
sequence for_to_do_loop_conversion(forloop, statement)
Try to convert a C-like for-loop into a Fortran-like do-loop.
sequence for_to_while_loop_conversion(expression, expression, expression, statement, extensions)
Build a sequence with a while-loop from for-loop parameters.
char vcid_control_controlizer[]
There are some TODO !!! RK.
static string c_test(test t, bool breakable)
bool empty_global_label_p(const char *gln)
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define gen_recurse(start, domain_number, flt, rwt)
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
void insert_control_in_arc(control c, control before, control after)
Insert a control node between 2 connected control nodes.
void unlink_2_control_nodes(control source, control target)
Remove all edged between 2 control nodes.
void display_linked_control_nodes(control c)
Display all the control nodes reached or reachable from c for debugging purpose.
void link_3_control_nodes(control c_test, control c_then, control c_else)
Add an edge between 2 control nodes.
void link_2_control_nodes(control source, control target)
Add an edge between 2 control nodes.
void remove_a_control_from_an_unstructured_without_relinking(control c)
It removes a control node from its successor and predecessor.
void free_a_control_without_its_statement(control c)
Remove a control node without touching its statement, its predecessors and successors,...
void remove_a_control_from_an_unstructured(control c)
Remove a control node from a control graph.
void print_control_nodes(list l)
Display identification of a list of control nodes.
void check_control_coherency(control c)
Test the coherency of a control node network from a control node.
void control_map_get_blocs(control c, list *l)
Build recursively the list of all controls reachable from a control of an unstructured.
void find_a_control_path(control b, control e, list *pp, list *vp, int dir)
Build recursively a control path from b to e.
static bool controlize_whileloop(control c_res, control succ, hash_table used_labels)
Computes the control graph of a Fortran or C while loop statement.
static control make_conditional_control(statement st)
In C, we can have some "goto" inside a block from outside, that translates as any complex control gra...
static bool covers_labels_p(statement st, hash_table used_labels)
Compute whether all the label references in a statement are in a given label name to statement list l...
static statement whileloop_test(statement sl)
Generate a test statement ts for exiting loop sl.
static bool controlize_forloop(control c_res, control succ, hash_table used_labels)
Computes the control graph of a C for loop statement.
bool controlize_statement(control c_res, control succ, hash_table used_labels)
Controlize a statement that is in a control node, that is restructure it to have a HCFG recursively (...
static hash_table Label_control
This maps label names to their (possible forward) control nodes.
statement forloop_header(statement)
control find_or_create_exit_control_node(list ctls, control succ)
FI: remake of function above, incomplete backward approach, now obsolete because the forward approach...
static bool controlize_sequence(control c_res, control succ, hash_table used_labels)
Computes the control graph of a sequence statement.
static void update_used_labels(hash_table used_labels, string name, statement st)
Mark a statement as related to a label.
static void init_label(string name, statement st)
INIT_LABEL puts the reference in the statement ST to the label NAME int the Label_statements table an...
statement forloop_inc(statement)
static void create_statements_of_labels(statement st)
Initialize the global Label_statements mapping for the module that associates for any label in the mo...
static hash_table Label_statements
This maps label names to the list of statements where they appear (either as definition or reference)...
static bool controlize_loop(control c_res, control succ, hash_table used_labels)
Computes the control graph of a Fortran do-loop statement.
control find_exit_control_node(list ctls, control succ)
Find the exit node of a sub-CFG defined by the list of nodes ctls and by the first node to execute wh...
static bool controlize_repeatloop(control c_res, control succ, hash_table used_labels)
Computes the control graph of a C repeat until loop statement.
#define ADD_PRED_AND_COPY_IF_NOT_ALREADY_HERE(pred, c)
static bool controlize_test(control c_res, control succ, hash_table used_labels)
Builds the control node of a test statement.
static void create_statements_of_label(statement st)
Update the global module-level Label_statements table according to the labels a statement references.
static void move_declaration_control_node_declarations_to_statement(list ctls)
Move all the declarations found in a list of control to a given statement.
static void add_proper_successor_to_predecessor(control pred, control c_res)
static control get_label_control(string name)
Get the control node associated to a label name.
#define ADD_PRED_IF_NOT_ALREADY_HERE(pred, c)
In C, we can have some "goto" inside a block from outside, that translate as any complex control grap...
static bool controlize_call(control c_res, control succ)
Controlize a call statement.
#define LABEL_TABLES_SIZE
static hash_table union_used_labels(hash_table l1, hash_table l2)
Unions 2 hash maps that list statements referencing labels into one.
statement forloop_test(statement)
static bool controlize_goto(control c_res, control succ, hash_table used_labels)
Deal with "goto" when building the HCFG.
statement hcfg(statement st)
Compute the hierarchical control flow graph (HCFG) of a statement.
#define UPDATE_CONTROL(c, s, pd, sc)
Update control c by setting its statement to s, by unioning its predecessor set with pd,...
statement unsugared_forloop_inc(statement sl)
statement unsugared_loop_inc(statement sl)
Do an index increment instruction for do-loop unsugaring.
statement unsugared_loop_test(statement sl)
Do a crude test of end of do-loop for do-loop unsugaring.
statement unsugared_whileloop_test(statement sl)
statement unsugared_whileloop_header(statement sl __attribute__((__unused__)))
statement unsugared_forloop_header(statement sl)
statement unsugared_forloop_test(statement sl)
statement unsugared_loop_header(statement sl)
LOOP_HEADER, LOOP_TEST and LOOP_INC build the desugaring phases of a do-loop L for the loop header (i...
void replace_entity(void *s, entity old, entity new)
per variable version of replace_entities.
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
instruction make_continue_instruction()
Creates a CONTINUE instruction, that is the FORTRAN nop, the ";" in C or the "pass" in Python for exa...
#define ENDP(l)
Test if a list is empty.
list gen_nreverse(list cp)
reverse a list in place
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)
list gen_once(const void *vo, list l)
Prepend an item to a list only if it is not already in the list.
list gen_copy_seq(list l)
Copy a list structure.
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
list gen_last(list l)
Return the last element of a list.
bool gen_in_list_p(const void *vo, const list lx)
tell whether vo belongs to lx
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
#define CDR(pcons)
Get the list less its first element.
#define list_undefined
Undefined list definition :-)
sequence statement_sequence(statement)
Get the sequence of a statement sequence.
list statement_block(statement)
Get the list of block statements of a statement sequence.
loop statement_loop(statement)
Get the loop of a statement.
test statement_test(statement)
Get the test of a statement.
whileloop statement_whileloop(statement)
Get the whileloop of a statement.
statement statement_goto(statement)
Get the goto of a statement.
forloop statement_forloop(statement)
Get the forloop of a statement.
bool unlabelled_statement_p(statement)
bool statement_test_p(statement)
bool statement_sequence_p(statement)
Statement classes induced from instruction type.
statement make_assign_statement(expression, expression)
void fix_block_statement_declarations(statement)
s is assumed to be a block statement and its declarations field is assumed to be correct,...
statement make_continue_statement(entity)
void fix_statement_attributes_if_sequence(statement)
Apply fix_sequence_statement_attributes() on the statement only if it really a sequence.
bool empty_comments_p(const char *)
statement normalize_statement(statement)
Make (a bit more) sure that s is gen_defined_p in spite of poor decision for empty fields and that st...
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.
list hash_get_default_empty_list(const hash_table h, const void *k)
Like hash_get() but returns an empty list instead of HASH_UNDEFINED_VALUE when a key is not found.
void * hash_table_scan(hash_table htp, void *hentryp_arg, void **pkey, void **pval)
struct _newgen_struct_control_ * control
enum language_utype get_prettyprint_language_tag()
#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 STATEMENT_ORDERING_UNDEFINED
mapping.h inclusion
string concatenate(const char *,...)
Return the concatenation of the given strings.
#define DEFINE_LOCAL_STACK(name, type)
#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_put_or_update(h, k, v)
void print_expression(expression e)
no file descriptor is passed to make is easier to use in a debugging stage.
string get_comment_sentinel()
Start a single line comment.
void set_bool_property(const char *, bool)
#define GREATER_THAN_OPERATOR_NAME
#define PLUS_OPERATOR_NAME
#define C_NOT_OPERATOR_NAME
#define is_instruction_block
soft block->sequence transition
#define empty_comments
Empty comments (i.e.
#define NOT_OPERATOR_NAME
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
entity entity_to_module_entity(entity e)
Find the enclosing module of an entity.
entity entity_empty_label(void)
bool entity_empty_label_p(entity e)
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
const char * label_local_name(entity e)
END_EOLE.
bool expression_call_p(expression e)
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
bool expression_reference_p(expression e)
Test if an expression is a reference.
bool entity_static_variable_p(entity)
return true if the entity is declared with the keyword static
expression variable_initial_expression(entity)
Returns a copy of the initial (i.e.
entity generic_clone_variable_with_unique_name(entity, statement, string, string, entity, bool)
clone a variable with a new name.
#define normalized_undefined
#define control_undefined
#define forloop_initialization(x)
#define control_predecessors(x)
#define forloop_increment(x)
#define instruction_goto(x)
#define value_unknown_p(x)
#define whileloop_evaluation(x)
#define statement_domain
newgen_sizeofexpression_domain_defined
#define instruction_undefined_p(x)
#define CONTROL(x)
CONTROL.
#define range_increment(x)
#define EXPRESSION(x)
EXPRESSION.
#define instruction_forloop_p(x)
#define instruction_undefined
#define statement_label(x)
#define expression_undefined
@ is_instruction_unstructured
@ is_instruction_whileloop
@ is_instruction_expression
#define instruction_tag(x)
#define whileloop_label(x)
#define sequence_statements(x)
#define statement_extensions(x)
#define instruction_sequence(x)
#define instruction_forloop(x)
#define control_successors(x)
#define control_undefined_p(x)
#define instruction_expression(x)
#define instruction_whileloop(x)
#define whileloop_body(x)
#define statement_declarations(x)
#define statement_instruction(x)
#define statement_comments(x)
#define statement_decls_text(x)
#define forloop_condition(x)
#define control_statement(x)
#define whileloop_condition(x)
#define statement_number(x)
#define evaluation_before_p(x)
#define sequence_undefined_p(x)
#define statement_undefined
#define STATEMENT(x)
STATEMENT.
#define entity_initial(x)
Pvecteur cp
pointeur sur l'egalite ou l'inegalite courante
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
The structure used to build lists in NewGen.