PIPS
module.c File Reference
#include <stdio.h>
#include <strings.h>
#include <string.h>
#include "linear.h"
#include "genC.h"
#include "ri.h"
#include "ri-util.h"
#include "workspace-util.h"
#include "control.h"
#include "pipsdbm.h"
#include "text-util.h"
#include "resources.h"
#include "properties.h"
#include "misc.h"
+ Include dependency graph for module.c:

Go to the source code of this file.

Functions

static statement update_unstructured_declarations (statement module_stat)
 FI: a short-term solution to fix declarations lost due to unstructured building by controlizer. More...
 
bool new_controlizer (const char *module_name)
 Transform a code with some goto and labels (typically generated by a parser) into a code that is a hierarchical control flow graph, the standard abstract syntax tree of PIPS (the RI). More...
 
bool controlizer (const char *module_name)
 The old controlizer user interface. More...
 

Function Documentation

◆ controlizer()

bool controlizer ( const char *  module_name)

The old controlizer user interface.

Transform a code with some goto and labels (typically generated by a parser) into a code that is a hierarchical control flow graph, the standard abstract syntax tree of PIPS (the RI).

Interface for pipsdbm and pipsmake

Should never arise

To have the debug in unspaghettify_statement() working:

The statement of a compilation unit is a long list of continue statements and it takes a long time to restructure although nothing is done in the end. So, let's skip this useless processing. SG:it may be ok to skip it, but we still need to call module_reorder ...

gen_copy_seq(statement_declarations(parsed_mod_stat))

By setting this property, we try to unspaghettify the control graph of the module:

With C code, some local declarations may have been lost by the (current) restructurer

Reorder the module, because we have a new statement structure.

Parameters
module_nameodule_name

Definition at line 224 of file module.c.

225 {
226  if (getenv(USE_NEW_CONTROLIZER_ENV_VAR_NAME) != NULL) {
227  pips_user_warning("Force the use of the new controlizer because a '%s' environment variable is defined\n", USE_NEW_CONTROLIZER_ENV_VAR_NAME);
229  }
230 
232  pips_assert("Module must be defined in symbol table",!entity_undefined_p(m));
233 
234  statement module_stat, parsed_mod_stat;
235 
236  // generate pragma string or expression using the correct language:
238  if(value_code_p(mv)) {
239  code c = value_code(mv);
241  } else {
242  /* Should never arise */
244  }
245 
247 
248  parsed_mod_stat = (statement) db_get_memory_resource(DBR_PARSED_CODE, module_name, true);
249  module_stat = copy_statement(parsed_mod_stat) ;
250  /* To have the debug in unspaghettify_statement() working: */
251  set_current_module_statement(module_stat);
252 
253  debug_on("CONTROL_DEBUG_LEVEL");
254  ifdebug(1){
255  statement_consistent_p(parsed_mod_stat);
256  statement_consistent_p(module_stat);
257  }
258 
259  /* The statement of a compilation unit is a long list of continue
260  statements and it takes a long time to restructure although
261  nothing is done in the end. So, let's skip this useless
262  processing.
263  SG:it may be ok to skip it, but we still need to call module_reorder ...
264  */
266  /* *module_stat can be re-used because control_graph reallocates
267  statements; do not show that to any student!
268  statement_instruction(module_stat) =
269  make_instruction(is_instruction_unstructured,
270  control_graph(module_stat));
271  Maintenant que je nettoie le code aussi avant le controlizer,
272  un programme sans instruction ne contient qu'un statement
273  RETURN, c'est a` dire un statement de CALL vers RETURN avec le
274  label 00000. Comme la ligne ci-dessus recycle le label et le
275  commentaire, on se retrouve avec un unstructured avec le label
276  et le commentaire du RETURN qu'il contient... En plus il y avait
277  une re'cursion de l'unstructured vers module_stat. :-(
278 
279  So now correct the label and the comment: */
280 
281  ifdebug(1) pips_assert("the module statement is consistent "
282  "before the controlizer is called",
283  statement_consistent_p(module_stat));
284 
285  module_stat = make_statement(entity_empty_label(),
287  MAKE_ORDERING(0,1),
290  control_graph(module_stat)),
291  NIL /* gen_copy_seq(statement_declarations(parsed_mod_stat))*/,
292  NULL,
295 
296  ifdebug(1) pips_assert("the module statement is consistent "
297  "after the controlizer call",
298  statement_consistent_p(module_stat));
299 
300  /* By setting this property, we try to unspaghettify the control graph
301  of the module: */
302  if (get_bool_property("UNSPAGHETTIFY_IN_CONTROLIZER"))
303  unspaghettify_statement(module_stat);
304 
305 
306  /* With C code, some local declarations may have been lost by the
307  (current) restructurer */
308  if(c_module_p(m))
309  module_stat = update_unstructured_declarations(module_stat);
310 
311  }
312 
313  /* Reorder the module, because we have a new statement structure. */
314  module_reorder(module_stat);
315 
316  ifdebug(1) statement_consistent_p(module_stat);
317 
318  DB_PUT_MEMORY_RESOURCE(DBR_CODE, module_name, module_stat);
319 
322 
323  debug_off();
324 
325  return true;
326 }
statement copy_statement(statement p)
STATEMENT.
Definition: ri.c:2186
bool statement_consistent_p(statement p)
Definition: ri.c:2195
statement make_statement(entity a1, intptr_t a2, intptr_t a3, string a4, instruction a5, list a6, string a7, extensions a8, synchronization a9)
Definition: ri.c:2222
instruction make_instruction(enum instruction_utype tag, void *val)
Definition: ri.c:1166
synchronization make_synchronization_none(void)
Definition: ri.c:2424
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
#define USE_NEW_CONTROLIZER_ENV_VAR_NAME
– control.h
Definition: control-local.h:33
bool controlizer(const char *module_name)
The old controlizer user interface.
Definition: module.c:224
static statement update_unstructured_declarations(statement module_stat)
FI: a short-term solution to fix declarations lost due to unstructured building by controlizer.
Definition: module.c:49
bool new_controlizer(const char *module_name)
Transform a code with some goto and labels (typically generated by a parser) into a code that is a hi...
Definition: module.c:102
void unspaghettify_statement(statement)
The real entry point of unspaghettify:
bool compilation_unit_p(const char *module_name)
The names of PIPS entities carry information about their nature.
Definition: entity_names.c:56
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....
if(!(yy_init))
Definition: genread_lex.c:1029
unstructured control_graph(statement)
CONTROL_GRAPH returns the control graph of the statement ST.
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
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
void set_prettyprint_language_from_property(enum language_utype native)
set the prettyprint language according to the property PRETTYPRINT_LANGUAGE @description If the prope...
Definition: language.c:103
#define debug_on(env)
Definition: misc-local.h:157
#define pips_user_warning
Definition: misc-local.h:146
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define debug_off()
Definition: misc-local.h:160
#define true
Definition: newgen_types.h:81
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
#define STATEMENT_NUMBER_UNDEFINED
default values
#define MAKE_ORDERING(u, s)
On devrait utiliser Newgen pour cela, mais comme on ne doit pas les utiliser directement (mais via st...
#define empty_comments
Empty comments (i.e.
bool c_module_p(entity m)
Test if a module "m" is written in C.
Definition: entity.c:2777
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
entity entity_empty_label(void)
Definition: entity.c:1105
extensions empty_extensions(void)
extension.c
Definition: extension.c:43
#define value_code_p(x)
Definition: ri.h:3065
#define entity_undefined_p(x)
Definition: ri.h:2762
@ is_instruction_unstructured
Definition: ri.h:1475
#define value_code(x)
Definition: ri.h:3067
#define code_language(x)
Definition: ri.h:792
#define language_tag(x)
Definition: ri.h:1590
@ is_language_fortran
Definition: ri.h:1566
#define entity_initial(x)
Definition: ri.h:2796
return(s1)
#define ifdebug(n)
Definition: sg.c:47

References c_module_p(), code_language, compilation_unit_p(), control_graph(), copy_statement(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, empty_comments, empty_extensions(), entity_empty_label(), entity_initial, entity_undefined_p, get_bool_property(), ifdebug, is_instruction_unstructured, is_language_fortran, language_tag, make_instruction(), MAKE_ORDERING, make_statement(), make_synchronization_none(), module_name(), module_name_to_entity(), module_reorder(), new_controlizer(), NIL, pips_assert, pips_user_warning, reset_current_module_entity(), reset_current_module_statement(), set_current_module_entity(), set_current_module_statement(), set_prettyprint_language_from_property(), statement_consistent_p(), STATEMENT_NUMBER_UNDEFINED, unspaghettify_statement(), update_unstructured_declarations(), USE_NEW_CONTROLIZER_ENV_VAR_NAME, value_code, and value_code_p.

Referenced by AddEntityToCompilationUnit(), new_controlizer(), outliner_independent(), and RemoveEntityFromCompilationUnit().

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

◆ new_controlizer()

bool new_controlizer ( const char *  module_name)

Transform a code with some goto and labels (typically generated by a parser) into a code that is a hierarchical control flow graph, the standard abstract syntax tree of PIPS (the RI).

module.c

Interface for pipsdbm and pipsmake

Should never happen

To have the debug in unspaghettify_statement() working:

The statement of a compilation unit is a long list of continue statements and it takes a long time to restructure although nothing is done in the end. So, let's skip this useless processing. SG:it may be ok to skip it, but we still need to call module_reorder ...

By setting this property, we try to unspaghettify the control graph of the module:

With C code, some local declarations may have been lost by the (current) restructurer. FI: not investigated; should be useless by now..

Reorder the module, because we have a new statement structure.

Parameters
module_nameodule_name

Definition at line 102 of file module.c.

103 {
104  if (getenv(USE_OLD_CONTROLIZER_ENV_VAR_NAME) != NULL) {
105  pips_user_warning("Force the use of the old controlizer because a '%s' environment variable is defined\n", USE_OLD_CONTROLIZER_ENV_VAR_NAME);
106  return controlizer(module_name);
107  }
108 
110  pips_assert("Module must be defined in symbol table",!entity_undefined_p(m));
111 
112  statement module_stat, parsed_mod_stat;
113 
114  // generate pragma string or expression using the correct language:
116  if(value_code_p(mv)) {
117  code c = value_code(mv);
119  } else {
120  /* Should never happen */
122  }
123 
125 
126  parsed_mod_stat = (statement) db_get_memory_resource(DBR_PARSED_CODE, module_name, true);
127  module_stat = copy_statement(parsed_mod_stat) ;
128  /* To have the debug in unspaghettify_statement() working: */
129  set_current_module_statement(module_stat);
130 
131  debug_on("CONTROL_DEBUG_LEVEL");
132  ifdebug(1){
133  statement_consistent_p(parsed_mod_stat);
134  statement_consistent_p(module_stat);
135  }
136 
137  /* The statement of a compilation unit is a long list of continue
138  statements and it takes a long time to restructure although
139  nothing is done in the end. So, let's skip this useless
140  processing.
141  SG:it may be ok to skip it, but we still need to call module_reorder ...
142  */
144  /* *module_stat can be re-used because control_graph reallocates
145  statements; do not show that to any student!
146  statement_instruction(module_stat) =
147  make_instruction(is_instruction_unstructured,
148  control_graph(module_stat));
149  Maintenant que je nettoie le code aussi avant le controlizer,
150  un programme sans instruction ne contient qu'un statement
151  RETURN, c'est a` dire un statement de CALL vers RETURN avec le
152  label 00000. Comme la ligne ci-dessus recycle le label et le
153  commentaire, on se retrouve avec un unstructured avec le label
154  et le commentaire du RETURN qu'il contient... En plus il y avait
155  une re'cursion de l'unstructured vers module_stat. :-(
156 
157  So now correct the label and the comment: */
158 
159  pips_assert("the module statement is consistent "
160  "before the controlizer is called",
161  statement_consistent_p(module_stat));
162 
163  module_stat = hcfg(module_stat);
164 
165  pips_assert("the module statement is consistent "
166  "after the controlizer call",
167  statement_consistent_p(module_stat));
168 
169  if (get_bool_property("FOR_TO_DO_LOOP_IN_CONTROLIZER")) {
170  gen_recurse(module_stat,
171  // Since for-loop statements can be nested,
172  // only restructure in a bottom-up way, :
175 
176  }
177 
178  if (get_bool_property("FOR_TO_WHILE_LOOP_IN_CONTROLIZER")) {
179  gen_recurse(module_stat,
180  // Since for-loop statements can be nested,
181  // only restructure in a bottom-up way, :
182  //forloop_domain, gen_true,
183  //transform_a_for_loop_into_a_while_loop);
186  }
187 
188  /* By setting this property, we try to unspaghettify the control graph
189  of the module: */
190  if (get_bool_property("UNSPAGHETTIFY_IN_CONTROLIZER"))
191  unspaghettify_statement(module_stat);
192 
193  /* With C code, some local declarations may have been lost by the
194  (current) restructurer. FI: not investigated; should be
195  useless by now.. */
196  if(c_module_p(m))
197  module_stat = update_unstructured_declarations(module_stat);
198 
199  }
200 
201  /* Reorder the module, because we have a new statement structure. */
202  module_reorder(module_stat);
203 
204  statement_consistent_p(module_stat);
205 
206  DB_PUT_MEMORY_RESOURCE(DBR_CODE, module_name, module_stat);
207 
210 
211  debug_off();
212 
213  return true;
214 }
#define USE_OLD_CONTROLIZER_ENV_VAR_NAME
The name of the one to force the use of the old controlizer:
Definition: control-local.h:35
void transform_a_for_loop_statement_into_a_while_loop(statement)
Same as above, but with no calls to ancestors.
void try_to_transform_a_for_loop_into_a_do_loop(forloop)
Try to to transform the C-like for-loops into Fortran-like do-loops.
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
statement hcfg(statement)
Compute the hierarchical control flow graph (HCFG) of a statement.
Definition: controlizer.c:2621
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
#define forloop_domain
newgen_extensions_domain_defined
Definition: ri.h:178
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362

References c_module_p(), code_language, compilation_unit_p(), controlizer(), copy_statement(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, entity_initial, entity_undefined_p, forloop_domain, gen_recurse, gen_true(), get_bool_property(), hcfg(), ifdebug, is_language_fortran, language_tag, module_name(), module_name_to_entity(), module_reorder(), pips_assert, pips_user_warning, reset_current_module_entity(), reset_current_module_statement(), set_current_module_entity(), set_current_module_statement(), set_prettyprint_language_from_property(), statement_consistent_p(), statement_domain, transform_a_for_loop_statement_into_a_while_loop(), try_to_transform_a_for_loop_into_a_do_loop(), unspaghettify_statement(), update_unstructured_declarations(), USE_OLD_CONTROLIZER_ENV_VAR_NAME, value_code, and value_code_p.

Referenced by controlizer().

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

◆ update_unstructured_declarations()

static statement update_unstructured_declarations ( statement  module_stat)
static

FI: a short-term solution to fix declarations lost due to unstructured building by controlizer.

Get all the declarations found (recursively) in the module

Get all the entities referenced in the module

To preserve the order, it would be better to collect variables and functions at the same time with a statement_to_referenced_or_called_entities()

Build a list of entities that are not declared anywhere:

Definition at line 49 of file module.c.

50 {
51  /* Get all the declarations found (recursively) in the module */
52  list dl = statement_to_declarations(module_stat);
53  /* Get all the entities referenced in the module */
54  list vl = statement_to_referenced_entities(module_stat);
55  list fl = statement_to_called_user_entities(module_stat);
56  /* To preserve the order, it would be better to collect variables
57  and functions at the same time with a
58  statement_to_referenced_or_called_entities()*/
59  list vfl = gen_nconc(vl, fl);
60  list udl = NIL;
64 
65  /* Build a list of entities that are not declared anywhere: */
66  MAP(ENTITY, e, {
67  if(!gen_in_list_p(e, dl) && !gen_in_list_p(e, cudl)
68  && !gen_in_list_p(e, udl) && !formal_parameter_p(e)
69  && !member_entity_p(e))
70  udl = gen_nconc(udl, CONS(ENTITY, e, NIL));
71  }, vfl);
72  gen_free_list(dl);
73 
74  if(!ENDP(udl)) {
75  ifdebug(8) {
76  pips_debug(8, "Lost declarations: ");
77  print_entities(udl);
78  }
79  if(statement_block_p(module_stat))
80  statement_declarations(module_stat)
81  = gen_nconc(statement_declarations(module_stat), udl);
82  else if(statement_unstructured_p(module_stat)) {
83  // might be OK...
84  // should only done on blocks?
85  statement_declarations(module_stat)
86  = gen_nconc(statement_declarations(module_stat), udl);
87  }
88  else {
89  module_stat = make_block_statement(CONS(STATEMENT, module_stat, NIL));
90  statement_declarations(module_stat)
91  = gen_nconc(statement_declarations(module_stat), udl);
92  }
93  }
94  return module_stat;
95 }
statement make_block_statement(list)
Make a block statement from a list of statement.
Definition: statement.c:616
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#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
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
bool gen_in_list_p(const void *vo, const list lx)
tell whether vo belongs to lx
Definition: list.c:734
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
bool statement_unstructured_p(statement)
Definition: statement.c:369
list statement_to_referenced_entities(statement)
Get a list of all variables referenced recursively within a statement:
Definition: statement.c:3428
list statement_to_called_user_entities(statement)
Get a list of all user function called recursively within a statement:
Definition: statement.c:3478
list statement_to_declarations(void *)
Get a list of all variables declared recursively within a statement.
Definition: statement.c:3253
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define statement_block_p(stat)
void print_entities(list l)
Definition: entity.c:167
bool member_entity_p(entity e)
Definition: entity.c:1921
bool formal_parameter_p(entity)
Definition: variable.c:1489
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define code_declarations(x)
Definition: ri.h:784
#define statement_declarations(x)
Definition: ri.h:2460
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
entity module_entity_to_compilation_unit_entity(entity m)
Retrieve the compilation unit containing a module definition.
Definition: module.c:116

References code_declarations, CONS, ENDP, ENTITY, entity_initial, formal_parameter_p(), gen_free_list(), gen_in_list_p(), gen_nconc(), get_current_module_entity(), ifdebug, make_block_statement(), MAP, member_entity_p(), module_entity_to_compilation_unit_entity(), NIL, pips_debug, print_entities(), STATEMENT, statement_block_p, statement_declarations, statement_to_called_user_entities(), statement_to_declarations(), statement_to_referenced_entities(), statement_unstructured_p(), and value_code.

Referenced by controlizer(), and new_controlizer().

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