PIPS
atomizer.c File Reference
#include "local.h"
#include "prettyprint.h"
#include "expressions.h"
+ Include dependency graph for atomizer.c:

Go to the source code of this file.

Macros

#define MEM_TO_TMP_SIZE   100
 – atomizer.c More...
 
#define MEM_VAR   1
 Useful for atomizer_of_expression(). More...
 
#define NO_MEM_VAR   0
 

Functions

static void initialize_global_variables (char *mod_name)
 =========================================================================== More...
 
static void reset_global_variables ()
 
static entity build_new_variable (entity module, basic b)
 
static bool indirection_test (reference ref, expression expr)
 
void normalize_wp65_code (statement stat)
 
static void rm_db_block (statement stat)
 
static statement rm_block_block_statement (statement stat)
 
bool atomizer (const string mod_name)
 =========================================================================== More...
 
void atomizer_of_unstructured (u)
 =========================================================================== More...
 
void atomizer_of_statement (statement stmt, Block *cb)
 =========================================================================== More...
 
void atomizer_of_block (instruction i)
 =========================================================================== More...
 
void atomizer_of_test (test t, Block *cb)
 =========================================================================== More...
 
void atomizer_of_loop (loop l, Block *cb)
 =========================================================================== More...
 
void atomizer_of_call (call c, Block *cb)
 =========================================================================== More...
 
void atomizer_of_intrinsic (call c, Block *cb)
 =========================================================================== More...
 
void atomizer_of_external (call c, Block *cb)
 =========================================================================== More...
 
list atomizer_of_expressions (list expl, Block *cb)
 =========================================================================== More...
 
expression atomizer_of_expression (expression exp, Block *cb, int mem_var)
 =========================================================================== More...
 
void atomizer_of_array_indices (expression exp, Block *cb)
 =========================================================================== More...
 

Variables

list l_inst = list_undefined
 FI: the following global variables are not declared STATIC because they also are used in codegen.c. More...
 
hash_table MemToTmp = hash_table_undefined
 These lists memorize all the new created entities of each type. More...
 
static graph mod_dg = graph_undefined
 Dependence graph of the current module. More...
 

Macro Definition Documentation

◆ MEM_TO_TMP_SIZE

#define MEM_TO_TMP_SIZE   100

– atomizer.c

package atomizer : Alexis Platonoff, juin 91

These functions produce atomic instructions.

An atomic instruction is an instruction that whether, loads a variable into a temporary variable, stores a variable from a temporary variable or computes numericals operations upon temporary variables.

The scalar variables have a special treatment. Indeed, these variables are loaded in temporaries and kept in them while they are used or defined. It is only when they are no more used that they are stored back. This treatment is done with the dependence graph.

Note : in the following, we'll distinguish two kinds of variables: the memory variables and the temporary variables. The firsts will be called variables, the latter temporaries. The temporaries should not appear in the dependence graph; ie. that there can not be any dependences upon the temporaries. The temporaries can also be called registers.

This phase produces variables and temporaries. The variables produced are prefixed : "AUX". The temporaries produced are prefixed : "TMP". Another kind of entities can be encounter, the NLCs. They have the same status as the temporaries, ie. they should not appear in the dependence graph. More, they have another property : an expression that contains only NLCs and is integer linear, is not decomposed by the atomizer, ie. it is considered as a constant. Gives the size of the hash table named "MemToTmp".

Definition at line 64 of file atomizer.c.

◆ MEM_VAR

#define MEM_VAR   1

Useful for atomizer_of_expression().

It tells if the function can return a variable (MEM_VAR) or if it must return a temporary.

Definition at line 69 of file atomizer.c.

◆ NO_MEM_VAR

#define NO_MEM_VAR   0

Definition at line 70 of file atomizer.c.

Function Documentation

◆ atomizer()

bool atomizer ( const string  mod_name)

===========================================================================

void atomizer(const char* module_name): computes the translation of Fortran instructions into Three Adresses Code instructions.

This translation is done after two pre-computations : _ The first one puts all the integer linear expressions into a normal pattern (see norm_exp.c). _ The second one removes all the defs with no def-use dependence.

Also, after the atomization, the module statement is reordered, and declarations are made for the new variables and temporaries.

The atomization uses the CODE, CUMULATED_EFFECTS and DG (dependence graph) resources.

Called functions: _ module_body_reorder() : control/control.c

COMPUTATION

All the expressions are put into a normal pattern : the NLCs in the innermost parenthesis.

All the defs with no def-use dependence are removed.

Module is atomized.

We reorder the module. It is necessary because new statements have been generated. The reordering will permit to reuse the generated code for further analysis.

We declare the new variables and the new temporaries.

insert_new_declarations(mod_name);

We save the new CODE.

Parameters
mod_nameod_name

Definition at line 226 of file atomizer.c.

227 {
229  entity module;
230  pips_user_warning("this transformation is being obsoleted by SIMD_ATOMIZER\nIt is no longer maintained and is likely to crash soon\n");
231 
232  debug_on("ATOMIZER_DEBUG_LEVEL");
233 
234  if(get_debug_level() > 0)
235  user_log("\n\n *** ATOMIZER for %s\n", mod_name);
236 
237  mod_stat = (statement) db_get_memory_resource(DBR_CODE, mod_name, true);
238 
239 
240 
242  set_cumulated_rw_effects((statement_effects)db_get_memory_resource(DBR_CUMULATED_EFFECTS,mod_name,true));
243 
246 
247  if (get_bool_property("ATOMIZE_INDIRECT_REF_ONLY"))
248  {
252  }
253  else {
254 
255 
256  initialize_global_variables(mod_name);
257 
258  /* COMPUTATION */
259 
260  /* All the expressions are put into a normal pattern : the NLCs in the
261  * innermost parenthesis.
262  */
264 
265  /* All the defs with no def-use dependence are removed. */
267 
268  /* Module is atomized. */
270 
271  /* We reorder the module. It is necessary because new statements have been
272  * generated. The reordering will permit to reuse the generated code for
273  * further analysis.
274  */
276 
277  /* We declare the new variables and the new temporaries. */
278  /* insert_new_declarations(mod_name); */
280 
282 
283  }
284  /* We save the new CODE. */
285  DB_PUT_MEMORY_RESOURCE(DBR_CODE, strdup(mod_name), mod_stat);
286 
290 
291  if(get_debug_level() > 0)
292  user_log("\n\n *** ATOMIZER done\n");
293 
294  debug_off();
295 
296  return(true);
297 }
void user_log(const char *format,...)
Definition: message.c:234
static void reset_global_variables()
Definition: atomizer.c:131
void normalize_wp65_code(statement stat)
Definition: atomizer.c:161
static void initialize_global_variables(char *mod_name)
===========================================================================
Definition: atomizer.c:105
void atomizer_of_statement(statement stmt, Block *cb)
===========================================================================
Definition: atomizer.c:381
static graph mod_dg
Dependence graph of the current module.
Definition: atomizer.c:98
static statement rm_block_block_statement(statement stat)
Definition: atomizer.c:199
bool defs_elim_of_statement(statement, graph)
===========================================================================
Definition: defs_elim.c:211
void normal_expression_of_statement(statement)
===========================================================================
Definition: norm_exp.c:123
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
void set_cumulated_rw_effects(statement_effects)
void reset_cumulated_rw_effects(void)
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
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
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
static statement mod_stat
We want to keep track of the current statement inside the recurse.
Definition: impact_check.c:41
#define debug_on(env)
Definition: misc-local.h:157
#define pips_user_warning
Definition: misc-local.h:146
#define debug_off()
Definition: misc-local.h:160
int get_debug_level(void)
GET_DEBUG_LEVEL returns the current debugging level.
Definition: debug.c:67
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
entity local_name_to_top_level_entity(const char *n)
This function try to find a top-level entity from a local name.
Definition: entity.c:1450
void discard_module_declaration_text(entity)
Discard the decls_text string of the module code to make the prettyprinter ignoring the textual decla...
Definition: variable.c:1696
char * strdup()
During the computation, the program has to deal with blocks of statements.

References atomizer_of_statement(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, defs_elim_of_statement(), discard_module_declaration_text(), get_bool_property(), get_debug_level(), initialize_global_variables(), local_name_to_top_level_entity(), mod_dg, mod_stat, module, module_reorder(), normal_expression_of_statement(), normalize_wp65_code(), pips_user_warning, reset_cumulated_rw_effects(), reset_current_module_entity(), reset_current_module_statement(), reset_global_variables(), rm_block_block_statement(), set_cumulated_rw_effects(), set_current_module_entity(), set_current_module_statement(), strdup(), and user_log().

+ Here is the call graph for this function:

◆ atomizer_of_array_indices()

void atomizer_of_array_indices ( expression  exp,
Block cb 
)

===========================================================================

void atomizer_of_array_indices(expression exp, Block *cb): Applies the translation on an array expression.

Only the indices of the array are translated, in order to have a list of temporary variables.

We translate all the indices expressions.

Parameters
expxp
cbb

Definition at line 932 of file atomizer.c.

935 {
937  list inds = reference_indices(array_ref);
938 
939  pips_debug(6, "begin : %s\n", expression_to_string(exp));
940 
941  /* We translate all the indices expressions. */
942  reference_indices(array_ref) = atomizer_of_expressions(inds, cb);
943 
944  pips_debug(6, "end : %s\n", expression_to_string(exp));
945 }
list atomizer_of_expressions(list expl, Block *cb)
===========================================================================
Definition: atomizer.c:811
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
string expression_to_string(expression e)
Definition: expression.c:77
#define syntax_reference(x)
Definition: ri.h:2730
#define reference_indices(x)
Definition: ri.h:2328
#define expression_syntax(x)
Definition: ri.h:1247
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207

References atomizer_of_expressions(), exp, expression_syntax, expression_to_string(), pips_debug, reference_indices, and syntax_reference.

Referenced by atomizer_of_expression().

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

◆ atomizer_of_block()

void atomizer_of_block ( instruction  i)

===========================================================================

void atomizer_of_block(instruction inst): Applies the translation on all the statements of the block of the instruction given in argument.

Note: the "instruction_tag" of "inst" must be a block, otherwise, it's a user error.

We enter a new block of statements, so we generate a new variable of type "Block". "last" representes the list of statements not translated yet. "first" representes the list of statements that are translated, plus the statements that were generated by them. The statement being translated (current statement) is the first of the "last" list. When the translation of a statement is done, it is put at the end of the "first" list.

Nothing to do!!

Initialization of the new "Block".

"cb->last" is the list of the statements not yet visited

Gets the current statement.

This current statement has not yet generated another statement.

Translation of the current statement.

The current statement is put at the end of the "first" list.

Since there could have been creations of statements in the list "cb->first" we have to update the block of the instruction.

Memory deallocation

Definition at line 473 of file atomizer.c.

475 {
476  Block *cb;
477 
478  debug(2, "atomizer_of_block", "begin BLOCK\n");
479 
481  user_error("atomizer_of_block", "Instruction is not a block");
482 
483  /* Nothing to do!! */
484  if(instruction_block(i) == NIL)
485  return;
486 
487  /* Initialization of the new "Block". */
488  cb = (Block *) malloc(sizeof(Block));
489  if (cb == (Block *) NULL)
490  user_error("atomizer_of_block", "Block malloc: no memory left");
491  cb->last = instruction_block(i);
492  cb->first = NIL;
493 
494  /* "cb->last" is the list of the statements not yet visited */
495  for(; cb->last != NIL; cb->last = CDR(cb->last) )
496  {
497  /* Gets the current statement. */
498  statement s = STATEMENT(CAR(cb->last));
499 
500  /* This current statement has not yet generated another statement. */
501  cb->stmt_generated = false;
502 
503  /* Translation of the current statement. */
504  atomizer_of_statement(s, cb);
505 
506  /* The current statement is put at the end of the "first" list. */
507  cb->first = gen_nconc(cb->first, CONS(STATEMENT, s, NIL));
508  }
509 
510  /* Since there could have been creations of statements in the list "cb->first"
511  * we have to update the block of the instruction.
512  */
513  instruction_block(i) = cb->first;
514 
515  /* Memory deallocation */
516  cb->first = NIL;
517  free( (char *) cb);
518 
519  debug(2, "atomizer_of_block", "end BLOCK\n");
520 }
void * malloc(YYSIZE_T)
void free(void *)
#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
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define user_error(fn,...)
Definition: misc-local.h:265
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
#define is_instruction_block
soft block->sequence transition
#define instruction_block(i)
#define instruction_tag(x)
Definition: ri.h:1511
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
bool stmt_generated
list first
list last

References atomizer_of_statement(), CAR, CDR, CONS, debug(), Block::first, free(), gen_nconc(), instruction_block, instruction_tag, is_instruction_block, Block::last, malloc(), NIL, STATEMENT, Block::stmt_generated, and user_error.

Referenced by atomizer_of_statement().

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

◆ atomizer_of_call()

void atomizer_of_call ( call  c,
Block cb 
)

===========================================================================

void atomizer_of_call(call c, Block *cb): Applies the translation on an instruction call.

The two main kinds of call are: _ external call, ie user_defined function or subroutine. _ intrinsic call.

The variable "cb" memorises the information about the block of statements that contains the call statement.

Evite d'atomiser un parame`tre inexistant ( :-) ) d'un intrinsic sans argument, du style * dans : write ... FMT=*... RK, 24/02/1994.

Parameters
cbb

Definition at line 660 of file atomizer.c.

663 {
664  entity e = call_function(c);
665  tag t = value_tag(entity_initial(e));
666  string n = entity_name(e);
667 
668  switch (t)
669  {
670  case is_value_code: { atomizer_of_external(c, cb); break; }
671  case is_value_intrinsic: {
672  if (call_arguments(c) == NIL)
673  /* Evite d'atomiser un parame`tre inexistant ( :-) )
674  d'un intrinsic sans argument, du style * dans :
675  write ... FMT=*...
676  RK, 24/02/1994. */
677  break;
678  atomizer_of_intrinsic(c, cb);
679  break;
680  }
681  case is_value_symbolic: break;
682  case is_value_constant: break;
683  case is_value_unknown:
684  pips_internal_error("unknown function %s", n);
685  break;
686  default: pips_internal_error("unknown tag %d", t);
687  }
688 }
void atomizer_of_external(call c, Block *cb)
===========================================================================
Definition: atomizer.c:753
void atomizer_of_intrinsic(call c, Block *cb)
===========================================================================
Definition: atomizer.c:699
#define pips_internal_error
Definition: misc-local.h:149
int tag
TAG.
Definition: newgen_types.h:92
#define value_tag(x)
Definition: ri.h:3064
#define call_function(x)
Definition: ri.h:709
@ is_value_intrinsic
Definition: ri.h:3034
@ is_value_unknown
Definition: ri.h:3035
@ is_value_constant
Definition: ri.h:3033
@ is_value_code
Definition: ri.h:3031
@ is_value_symbolic
Definition: ri.h:3032
#define entity_name(x)
Definition: ri.h:2790
#define call_arguments(x)
Definition: ri.h:711
#define entity_initial(x)
Definition: ri.h:2796

References atomizer_of_external(), atomizer_of_intrinsic(), call_arguments, call_function, entity_initial, entity_name, is_value_code, is_value_constant, is_value_intrinsic, is_value_symbolic, is_value_unknown, NIL, pips_internal_error, and value_tag.

Referenced by atomizer_of_expression(), and atomizer_of_statement().

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

◆ atomizer_of_expression()

expression atomizer_of_expression ( expression  exp,
Block cb,
int  mem_var 
)

===========================================================================

expression atomizer_of_expression(expression exp, Block *cb, int mem_var): Applies the translation on an expression.

It consists in assigning a new temporary variable to the expression, while the sub-expressions that it may contain are recursively translated.

If "exp" is only composed of NLCs variables (eventually a constant term), then the expression is treated like a constant, ie unchanged. NLC means Normalized Loop Counter.

The translation of expressions that reference a variable is not done only if the flag "mem_var" has the value "MEM_VAR". Otherwise, the variable is assigned to a temporary variable. The function "atomizer_of_array_indices()" translates the list of indices (when not empty) of the variable given in argument. Note: a scalar variable is an array with an empty list of indices.

The variable "cb" memorises the information about the block of statements that contains the expression.

An expression that is integer linear and is exclusively composed of NLCs is considered like a constant, ie not translated.

Two cases : _ a "real" call, ie an intrinsic or external function _ a constant

Evite d'atomiser un parame`tre inexistant ( :-) ) d'un intrinsic sans argument, du style * dans : write ... FMT=*... RK, 24/02/1994.

Translates the arguments of the call.

Generates the assign statement, and put it into the current block.

Constant value.

Parameters
expxp
cbb
mem_varem_var

Definition at line 849 of file atomizer.c.

853 {
856  bool IS_NLC_LINEAR = false;
857 
858  pips_debug(5, "begin : %s\n",
860 
861  /* An expression that is integer linear and is exclusively composed of NLCs
862  * is considered like a constant, ie not translated.
863  */
865  IS_NLC_LINEAR = true;
866 
867  switch(syntax_tag(sy))
868  {
869  case is_syntax_reference:
870  {
872 
873  if ( (mem_var == MEM_VAR) || IS_NLC_LINEAR )
874  ret_exp = exp;
875  else
876  ret_exp = assign_tmp_to_exp(exp, cb);
877  break;
878  }
879  case is_syntax_call:
880  {
881  call c = syntax_call(sy);
882 
883  /* Two cases : _ a "real" call, ie an intrinsic or external function
884  * _ a constant
885  */
886  if( ! call_constant_p(c) )
887  {
888  if ((call_arguments(c) == NIL)
890  /* Evite d'atomiser un parame`tre inexistant ( :-) )
891  d'un intrinsic sans argument, du style * dans :
892  write ... FMT=*...
893  RK, 24/02/1994. */
894  ret_exp = exp;
895  break;
896  }
897  else {
898  /* Translates the arguments of the call. */
899  if( ! IS_NLC_LINEAR )
900  atomizer_of_call(c, cb);
901 
902  /* Generates the assign statement, and put it into the current block. */
903  ret_exp = assign_tmp_to_exp(exp, cb);
904  }}
905  else /* Constant value. */
906  ret_exp = exp;
907  break;
908  }
909  case is_syntax_range:
910  {
911  debug(6, "atomizer_of_expression", " Expression RANGE\n");
912  ret_exp = exp;;
913  break;
914  }
915  default : pips_internal_error("Bad syntax tag");
916  }
917  pips_debug(5, "end : %s\n",
918  expression_to_string(ret_exp));
919 
920  return(ret_exp);
921 }
void atomizer_of_call(call c, Block *cb)
===========================================================================
Definition: atomizer.c:660
void atomizer_of_array_indices(expression exp, Block *cb)
===========================================================================
Definition: atomizer.c:932
#define MEM_VAR
Useful for atomizer_of_expression().
Definition: atomizer.c:69
expression assign_tmp_to_exp(expression, Block *)
===========================================================================
Definition: codegen.c:155
bool nlc_linear_expression_p(expression)
===========================================================================
Definition: utils.c:78
#define call_constant_p(C)
Definition: flint_check.c:51
#define syntax_tag(x)
Definition: ri.h:2727
#define value_intrinsic_p(x)
Definition: ri.h:3074
@ is_syntax_range
Definition: ri.h:2692
@ is_syntax_call
Definition: ri.h:2693
@ is_syntax_reference
Definition: ri.h:2691
#define expression_undefined
Definition: ri.h:1223
#define syntax_call(x)
Definition: ri.h:2736

References assign_tmp_to_exp(), atomizer_of_array_indices(), atomizer_of_call(), call_arguments, call_constant_p, call_function, debug(), entity_initial, exp, expression_syntax, expression_to_string(), expression_undefined, is_syntax_call, is_syntax_range, is_syntax_reference, MEM_VAR, NIL, nlc_linear_expression_p(), pips_debug, pips_internal_error, syntax_call, syntax_tag, and value_intrinsic_p.

Referenced by atomizer_of_expressions(), atomizer_of_external(), atomizer_of_intrinsic(), atomizer_of_loop(), and atomizer_of_test().

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

◆ atomizer_of_expressions()

list atomizer_of_expressions ( list  expl,
Block cb 
)

===========================================================================

list atomizer_of_expressions(list expl, Block *cb): Applies the translation on a list of expressions.

The variable "cb" memorises the information about the block of statements that contains the expressions.

Returns a list of expressions containing the translated expressions.

Parameters
explxpl
cbb

Definition at line 811 of file atomizer.c.

814 {
815  list newl;
816  expression exp, trad_exp;
817  for (newl = NIL; expl != NIL; expl = CDR(expl))
818  {
819  exp = EXPRESSION(CAR(expl));
820  trad_exp = atomizer_of_expression(exp, cb, NO_MEM_VAR);
821  newl = gen_nconc(newl, CONS(EXPRESSION, trad_exp, NIL));
822  }
823  return newl;
824 }
#define NO_MEM_VAR
Definition: atomizer.c:70
expression atomizer_of_expression(expression exp, Block *cb, int mem_var)
===========================================================================
Definition: atomizer.c:849
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217

References atomizer_of_expression(), CAR, CDR, CONS, exp, EXPRESSION, gen_nconc(), NIL, and NO_MEM_VAR.

Referenced by atomizer_of_array_indices(), atomizer_of_external(), atomizer_of_intrinsic(), and atomizer_of_test().

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

◆ atomizer_of_external()

void atomizer_of_external ( call  c,
Block cb 
)

===========================================================================

void atomizer_of_external(call c, block *cb): Translates the arguments of the call to an external function.

In fact, these arguments are kept as memory variable. When, the argument is an expression containing a "call" (a real call to a function and not a call to a constant), this expression is assigned to a new auxiliary variable which takes its place in the list of arguments. It is a variable, not a temporary (see the introduction at the beginning of this file).

Called functions : _ make_entity_expression() : ri-util/util.c _ make_assign_statement() : ri-util/statement.c

All the argument expressions are scanned. If an expression is not a reference (then, it is a call), we create an auxiliary variable. The expression is assigned to this new variable which is given in argument to the function, instead of the expression. If it is a reference, the corresponfding key (if it exists) in the hash table MemToTmp is deleted.

Parameters
cbb

Definition at line 753 of file atomizer.c.

756 {
757  list args, new_args;
758 
759  args = call_arguments(c);
760  new_args = NIL;
761 
762  /* All the argument expressions are scanned. If an expression is not a
763  * reference (then, it is a call), we create an auxiliary variable.
764  * The expression is assigned to this new variable which is given in
765  * argument to the function, instead of the expression.
766  * If it is a reference, the corresponfding key (if it exists) in the
767  * hash table MemToTmp is deleted.
768  */
769  for(; args != NIL; args = CDR(args))
770  {
771  expression ae = EXPRESSION(CAR(args));
773  {
775  (void) hash_del(MemToTmp, (char *) reference_variable(ar));
776  reference_indices(ar) =
778  new_args = gen_nconc(new_args, CONS(EXPRESSION, ae, NIL));
779  }
780  else
781  {
782  call arg_call = syntax_call(expression_syntax(ae));
783  if(call_constant_p(arg_call))
784  new_args = gen_nconc(new_args, CONS(EXPRESSION, ae, NIL));
785  else
786  {
788  basic aux_basic = basic_of_expression(tmp);
789  entity aux_ent = make_new_entity(aux_basic, AUX_ENT);
792  new_args = gen_nconc(new_args, CONS(EXPRESSION, aux, NIL));
793  }
794  }
795  }
796 
797  call_arguments(c) = new_args;
798 }
#define AUX_ENT
hash_table MemToTmp
These lists memorize all the new created entities of each type.
Definition: atomizer.c:95
void put_stmt_in_Block(statement, Block *)
codegen.c
Definition: codegen.c:89
statement make_assign_statement(expression, expression)
Definition: statement.c:583
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.
Definition: hash.c:439
expression make_entity_expression(entity e, cons *inds)
Definition: expression.c:176
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
entity make_new_entity(basic, int)
Definition: variable.c:898
#define reference_variable(x)
Definition: ri.h:2326
int aux
Definition: solpip.c:104

References atomizer_of_expression(), atomizer_of_expressions(), aux, AUX_ENT, basic_of_expression(), call_arguments, call_constant_p, CAR, CDR, CONS, EXPRESSION, expression_syntax, gen_nconc(), hash_del(), is_syntax_reference, make_assign_statement(), make_entity_expression(), make_new_entity(), MEM_VAR, MemToTmp, NIL, put_stmt_in_Block(), reference_indices, reference_variable, syntax_call, syntax_reference, and syntax_tag.

Referenced by atomizer_of_call().

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

◆ atomizer_of_intrinsic()

void atomizer_of_intrinsic ( call  c,
Block cb 
)

===========================================================================

void atomizer_of_intrinsic(call c, block *cb): translates the arguments of the intrinsic function. It treats two cases: assign call, and others.

Assign calls are treated differently because the first argument is the left-hand-side, so this argument is translated with the MEM_VAR option.

Assign expressions.

If the rhs expression is integer linear and exclusively composed of NLC variables, it is considered like a constant, ie not translated. Otherwise, it is translated normaly.

Translation of the lhs expression. We keep the memory variable.

The lhs variable is stored, so it is delete from MemToTmp.

The call is not an assignment, then each arguments is translated.

Parameters
cbb

Definition at line 699 of file atomizer.c.

702 {
704  {
705  entity lhs_entity;
706  expression lhs, rhs;
707 
708  /* Assign expressions. */
709  lhs = EXPRESSION(CAR(call_arguments(c)));
710  rhs = EXPRESSION(CAR(CDR(call_arguments(c))));
711 
712  pips_debug(4, "ASSIGN CALL: %s = %s\n",
714  expression_to_string(rhs));
715 
716  /* If the rhs expression is integer linear and exclusively composed of NLC
717  * variables, it is considered like a constant, ie not translated.
718  * Otherwise, it is translated normaly.
719  */
720  if(! nlc_linear_expression_p(rhs))
721  rhs = atomizer_of_expression(rhs, cb, NO_MEM_VAR);
722 
723  /* Translation of the lhs expression. We keep the memory variable. */
724  lhs = atomizer_of_expression(lhs, cb, MEM_VAR);
725 
726  /* The lhs variable is stored, so it is delete from MemToTmp. */
728  (void) hash_del(MemToTmp, (char *) lhs_entity);
729 
730  call_arguments(c) = CONS(EXPRESSION, lhs, CONS(EXPRESSION, rhs, NIL));
731  }
732  else
733  /* The call is not an assignment, then each arguments is translated. */
735 }
#define ENTITY_ASSIGN_P(e)

References atomizer_of_expression(), atomizer_of_expressions(), call_arguments, call_function, CAR, CDR, CONS, ENTITY_ASSIGN_P, EXPRESSION, expression_syntax, expression_to_string(), hash_del(), MEM_VAR, MemToTmp, NIL, nlc_linear_expression_p(), NO_MEM_VAR, pips_debug, reference_variable, and syntax_reference.

Referenced by atomizer_of_call().

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

◆ atomizer_of_loop()

void atomizer_of_loop ( loop  l,
Block cb 
)

===========================================================================

void atomizer_of_loop(loop l, Block *cb): Applies the translation on an instruction loop.

All written variables of the loop are removed from MemToTmp.

The variable "cb" memorizes the information about the block of statements that contains the loop statement.

Called functions: _ entity_scalar_p() : ri-util/entity.c _ make_block_with_stmt() : loop_normalize/utils.c

We have to remove from MemToTmp all the (scalars) variables that are written in this loop.

Translation of the three expressions of the loop range.

Afterwards, the body statement of the loop is translated. If this statement is not a block of statements, then it is put inside one (the resulting block contains only one statement !!).

Parameters
cbb

Definition at line 603 of file atomizer.c.

606 {
607 
608  list cumu_effs, lce;
609  statement stmt;
610  range r;
611 
612  debug(2, "atomizer_of_loop", "begin LOOP: %s\n",
614 
615  /* We have to remove from MemToTmp all the (scalars) variables that are
616  * written in this loop.
617  */
618  stmt = STATEMENT(CAR(cb->last));
619  cumu_effs = load_rw_effects_list(stmt);
620  for(lce = cumu_effs; lce != NIL; lce = CDR(lce))
621  {
622  effect eff = EFFECT(CAR(lce));
624  if( entity_scalar_p(eff_e) &&
626  {
627  (void) hash_del(MemToTmp, (char *) eff_e);
628  }
629  }
630 
631  /* Translation of the three expressions of the loop range. */
632  r = loop_range(l);
636 
637  /* Afterwards, the body statement of the loop is translated. If this
638  * statement is not a block of statements, then it is put inside one (the
639  * resulting block contains only one statement !!).
640  */
643 
644  debug(2, "atomizer_of_loop", "end LOOP\n");
645 }
list load_rw_effects_list(statement)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define effect_action(x)
Definition: effects.h:642
#define action_tag(x)
Definition: effects.h:310
@ is_action_write
Definition: effects.h:293
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
statement make_block_with_stmt_if_not_already(statement)
Build a statement block from a statement if not already a statement block.
Definition: statement.c:768
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_scalar_p(entity)
The concrete type of e is a scalar type.
Definition: variable.c:1113
#define loop_body(x)
Definition: ri.h:1644
#define range_upper(x)
Definition: ri.h:2290
#define range_increment(x)
Definition: ri.h:2292
#define range_lower(x)
Definition: ri.h:2288
#define loop_range(x)
Definition: ri.h:1642
#define loop_index(x)
Definition: ri.h:1640
Definition: statement.c:54

References action_tag, atomizer_of_expression(), atomizer_of_statement(), CAR, CDR, debug(), EFFECT, effect_action, effect_any_reference, entity_local_name(), entity_scalar_p(), hash_del(), is_action_write, Block::last, load_rw_effects_list(), loop_body, loop_index, loop_range, make_block_with_stmt_if_not_already(), MemToTmp, NIL, NO_MEM_VAR, range_increment, range_lower, range_upper, reference_variable, and STATEMENT.

Referenced by atomizer_of_statement().

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

◆ atomizer_of_statement()

void atomizer_of_statement ( statement  stmt,
Block cb 
)

===========================================================================

void atomizer_of_statement(statement stmt, Block *cb): computes the translation from Fortran to Three Addresses Code (ATOMIZER) of a statement ("stmt").

This function can be called in two different cases: _ If "cb" is NULL, then "stmt" is taken from a control C of the control graph. In such case, we have to find out where is the block in which we'll put the statements created by the translation of "stmt". . if "stmt" is a block, then this is it. . else, it is the predecessor of C. This control is obtained by the function find_control_block(). _ Else, "stmt" is one of the statements of a block, its creations are put in this block.

The "cb" variable refers to the current block of statements where "stmt" is.

Initialisation of "cb", if it is a NULL pointer.

The control in which the created statements are put is not the same as the control of "stmt".

We get the control in which we'll put our new statements.

We create the structure that will keep the created statements during the computation, before putting them in the control "c".

Computation of "stmt".

Updates of the control graph, if the generated statements are not put in the same control as "stmt".

The created statements are put in the control just before the control of the statement that created them.

Memory deallocation

Parameters
stmttmt
cbb

Definition at line 381 of file atomizer.c.

384 {
385  instruction inst;
386  bool stmt_with_remote_control_block = false;
388 
389  debug(2, "atomizer_of_statement", "begin STATEMENT\n");
390 
391  inst = statement_instruction(stmt);
392 
393  /* Initialisation of "cb", if it is a NULL pointer. */
394  if(cb == (Block *) NULL)
396  {
397  /* The control in which the created statements are put is not the same
398  * as the control of "stmt".
399  */
400  stmt_with_remote_control_block = true;
401 
402  /* We get the control in which we'll put our new statements. */
404 
405  /* We create the structure that will keep the created statements
406  * during the computation, before putting them in the control "c".
407  */
408  cb = (Block *) malloc(sizeof(Block));
409  if (cb == (Block *) NULL)
410  user_error("atomizer_of_statement", "Block malloc: no memory left");
411  cb->first = NIL;
412  cb->last = CONS(STATEMENT, stmt, NIL);
413  cb->stmt_generated = false;
414  }
415 
416  /* Computation of "stmt". */
417  switch(instruction_tag(inst))
418  {
419  case is_instruction_block : { atomizer_of_block(inst); break; }
421  break; }
423  break; }
425  break; }
426  case is_instruction_goto : break;
429  break; }
430  default : pips_internal_error("Bad instruction tag");
431  }
432 
433  /* Updates of the control graph, if the generated statements are not put in
434  * the same control as "stmt".
435  */
436  if(stmt_with_remote_control_block)
437  {
438  /* The created statements are put in the control just before the control
439  * of the statement that created them.
440  */
442 
443  /* Memory deallocation */
444  if (cb != (Block *) NULL)
445  {
446  cb->first = NIL;
447  cb->last = NIL;
448  free((char *) cb);
449  }
450  }
451  debug(2, "atomizer_of_statement", "end STATEMENT\n");
452 }
void atomizer_of_block(instruction i)
===========================================================================
Definition: atomizer.c:473
void atomizer_of_test(test t, Block *cb)
===========================================================================
Definition: atomizer.c:543
void atomizer_of_loop(loop l, Block *cb)
===========================================================================
Definition: atomizer.c:603
void atomizer_of_unstructured(u)
===========================================================================
Definition: atomizer.c:326
control find_control_block(control)
===========================================================================
Definition: control.c:115
#define control_undefined
Definition: ri.h:916
#define instruction_loop(x)
Definition: ri.h:1520
@ is_instruction_goto
Definition: ri.h:1473
@ is_instruction_unstructured
Definition: ri.h:1475
@ is_instruction_test
Definition: ri.h:1470
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_loop
Definition: ri.h:1471
#define statement_instruction(x)
Definition: ri.h:2458
#define instruction_call(x)
Definition: ri.h:1529
#define control_statement(x)
Definition: ri.h:941
#define instruction_test(x)
Definition: ri.h:1517
#define instruction_unstructured(x)
Definition: ri.h:1532

References atomizer_of_block(), atomizer_of_call(), atomizer_of_loop(), atomizer_of_test(), atomizer_of_unstructured(), CONS, control_statement, control_undefined, debug(), find_control_block(), Block::first, free(), instruction_block, instruction_call, instruction_loop, instruction_tag, instruction_test, instruction_unstructured, is_instruction_block, is_instruction_call, is_instruction_goto, is_instruction_loop, is_instruction_test, is_instruction_unstructured, Block::last, malloc(), NIL, pips_internal_error, STATEMENT, statement_instruction, Block::stmt_generated, and user_error.

Referenced by atomizer(), atomizer_of_block(), atomizer_of_loop(), atomizer_of_test(), and atomizer_of_unstructured().

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

◆ atomizer_of_test()

void atomizer_of_test ( test  t,
Block cb 
)

===========================================================================

void atomizer_of_test(test t, Block *cb): Applies the translation on an instruction test.

It consists in translating the three arguments of the test instruction : the condition expression and the two conditional statements (true, false).

The condition argument is an expression which may contain a logical intrinsic operator : "x op y" or "op x", with "op" in (<, =, >=, etc). In such case, the tranlation does not assign a temporary for the call expression associated with the operator, it only translates the arguments of the logical operator.

The variable "cb" memorises the information about the block of statements that contains the test statement.

Called functions : _ make_block_with_stmt() : loop_normalize/utils.c

If the expression is a call to a intrinsic operation, only its arguments are translated. Note : it is not tested that the intrinsic is a logical operator. In fact, Fortran requires it.

Else, the conditional expression is translated, and the returned expression must be a temporary (NO_MEM_VAR).

Afterwards, the two conditional statements are translated. If one of these statements is not a block of statements, then it is put inside one (the resulting block contains only one statement !!).

Parameters
cbb

Definition at line 543 of file atomizer.c.

546 {
547  expression cond = test_condition(t);
548 
549  debug(2, "atomizer_of_test", "begin TEST\n");
550 
552  /* If the expression is a call to a intrinsic operation,
553  * only its arguments
554  * are translated.
555  * Note : it is not tested that the intrinsic is a logical
556  * operator. In fact,
557  * Fortran requires it.
558  */
559  {
562 
563  debug(3, "atomizer_of_test", "CONDITION: %s\n",
565  }
566  else
567  /* Else, the conditional expression is translated,
568  * and the returned expression
569  * must be a temporary (NO_MEM_VAR).
570  */
572 
573  /* Afterwards, the two conditional statements are translated. If one of these
574  * statements is not a block of statements, then it is put inside one (the
575  * resulting block contains only one statement !!).
576  */
577  debug(2, "atomizer_of_test", "begin TEST IF\n");
580 
581  debug(2, "atomizer_of_test", "begin TEST ELSE\n");
584 
585  debug(2, "atomizer_of_test", "end TEST\n");
586 }
struct cons * list
Definition: newgen_types.h:106
bool expression_intrinsic_operation_p(expression exp)
bool expression_intrinsic_operation_p(expression exp): Returns true if "exp" is an expression with a ...
Definition: expression.c:1949
#define test_false(x)
Definition: ri.h:2837
#define test_true(x)
Definition: ri.h:2835
#define test_condition(x)
Definition: ri.h:2833

References atomizer_of_expression(), atomizer_of_expressions(), atomizer_of_statement(), call_arguments, call_function, debug(), entity_local_name(), expression_intrinsic_operation_p(), expression_syntax, make_block_with_stmt_if_not_already(), NO_MEM_VAR, syntax_call, test_condition, test_false, and test_true.

Referenced by atomizer_of_statement().

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

◆ atomizer_of_unstructured()

void atomizer_of_unstructured ( )

===========================================================================

void atomizer_of_unstructured(unstructured u): Computes the transformation of the unstructured "u".

This unstructured contains the control graph. In the control graph, some nodes (of Newgen type "control") have a statement that is not a "block" of statements. As we need, almost always, to add new instructions before the IFs and DOs, we have to change the control graph by adding nodes : For each node V with a "control_statement" that is not a "block", we generate a node Vnew that contain a "block" with no instruction. This node Vnew has the same predecessors as V, and has V as successor; the node V keeps the same successors, but his predecessor became Vnew.

So, for each such node V, when the translation produces instructions, we need to know the corresponding Vnew, in which we put the new instructions.

That is why we use a global variable "l_inst" and a code of CONTROL_MAP with some modifications (see below). The list "l_inst" contains the instructions for which we create Vnew. The modified code of CONTROL_MAP uses a function atom_get_blocs() that creates new nodes when needed, and updates the list "l_inst".

The following code is a modification of CONTROL_MAP, from control/control.h. This code uses atom_get_blocs() which is a modification of get_blocs() (in control/control.h).

Definition at line 326 of file atomizer.c.

328 {
329  extern list l_inst;
330 
331  list blocs = NIL ;
332  l_inst = NIL;
333 
334  debug(1, "atomizer_of_unstructured", "begin UNSTRUCTURED\n");
335 
336  /* The following code is a modification of CONTROL_MAP,
337  * from control/control.h. This code uses atom_get_blocs() which is
338  * a modification of get_blocs() (in control/control.h).
339  */
340 {
341  cons *_cm_list = blocs ;
342  if( _cm_list == NIL )
343  {
344  atom_get_blocs(unstructured_control(u), &_cm_list ) ;
345  _cm_list = gen_nreverse( _cm_list ) ;
346  }
347  MAPL( _cm_ctls, {control ctl = CONTROL( CAR( _cm_ctls )) ;
348  (void) find_control_block(ctl);
351  (Block *) NULL) ;},
352  _cm_list ) ;
353  if( blocs == NIL )
354  blocs = _cm_list ;
355 }
356 
357  gen_free_list( blocs ) ;
358 
359  debug(1, "atomizer_of_unstructured", "end UNSTRUCTURED\n");
360 }
list l_inst
FI: the following global variables are not declared STATIC because they also are used in codegen....
Definition: atomizer.c:79
void atom_get_blocs(control, cons **)
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#define MAPL(_map_list_cp, _code, _l)
Apply some code on the addresses of all the elements of a list.
Definition: newgen_list.h:203
void hash_table_clear(hash_table htp)
Clears all entries of a hash table HTP.
Definition: hash.c:305
#define unstructured_control
After the modification in Newgen: unstructured = entry:control x exit:control we have create a macro ...
#define CONTROL(x)
CONTROL.
Definition: ri.h:910

References atom_get_blocs(), atomizer_of_statement(), CAR, CONTROL, control_statement, debug(), find_control_block(), gen_free_list(), gen_nreverse(), hash_table_clear(), l_inst, MAPL, MemToTmp, NIL, and unstructured_control.

Referenced by atomizer_of_statement().

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

◆ build_new_variable()

static entity build_new_variable ( entity  module,
basic  b 
)
static

Definition at line 147 of file atomizer.c.

148 {
149  pips_assert("true", b==b);
152  return ent;
153 }
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
entity make_new_module_variable(entity, int)
Make a new module integer variable of name X<d>.
Definition: variable.c:830
void AddEntityToDeclarations(entity, entity)
END_EOLE.
Definition: variable.c:108

References AddEntityToDeclarations(), make_new_module_variable(), module, and pips_assert.

Referenced by normalize_wp65_code().

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

◆ indirection_test()

static bool indirection_test ( reference  ref,
expression  expr 
)
static

Definition at line 155 of file atomizer.c.

156 {
157  pips_assert("true", ref==ref);
159 }
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
#define NORMALIZE_EXPRESSION(e)
#define normalized_linear_p(x)
Definition: ri.h:1779

References NORMALIZE_EXPRESSION, normalized_linear_p, pips_assert, and ref.

Referenced by normalize_wp65_code().

+ Here is the caller graph for this function:

◆ initialize_global_variables()

static void initialize_global_variables ( char *  mod_name)
static

===========================================================================

static void initialize_global_variables(char *mod_name) : Initializes the global variables used through out all the computation of atomizer.

set_current_module_entity(local_name_to_top_level_entity(mod_name));

The last argument says if the resource is to be modified or not :

  • false : it is not modified
  • true : it is modified

Definition at line 105 of file atomizer.c.

107 {
108  /* set_current_module_entity(local_name_to_top_level_entity(mod_name)); */
109 
110  /* The last argument says if the resource is to be modified or not :
111  * - false : it is not modified
112  * - true : it is modified
113  */
115  db_get_memory_resource(DBR_CUMULATED_EFFECTS, mod_name, false));
116 
117  mod_dg = (graph) db_get_memory_resource(DBR_DG, mod_name, true);
118 
120 
122 
124  real_entities = NIL;
128  char_entities = NIL;
129 }
#define MEM_TO_TMP_SIZE
– atomizer.c
Definition: atomizer.c:64
void set_rw_effects(statement_effects)
void reset_rw_effects(void)
struct _newgen_struct_graph_ * graph
Definition: graph.h:31
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
@ hash_pointer
Definition: newgen_hash.h:32
list double_entities
list real_entities
list complex_entities
list logical_entities
list char_entities
list integer_entities
Make a new variable entity which name is one letter prefix + one incrementing number.
Definition: ri-util.h:2787

References char_entities, complex_entities, db_get_memory_resource(), double_entities, hash_pointer, hash_table_make(), integer_entities, logical_entities, MEM_TO_TMP_SIZE, MemToTmp, mod_dg, NIL, real_entities, reset_rw_effects(), and set_rw_effects().

Referenced by atomizer().

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

◆ normalize_wp65_code()

void normalize_wp65_code ( statement  stat)

reference test

function call test

test condition test

range arguments test

whileloop condition test

new variable

Parameters
stattat

Definition at line 161 of file atomizer.c.

162 {
164  atomize_as_required(stat,
165  indirection_test, /* reference test */
166  (bool (*)(call,expression)) gen_false2, /* function call test */
167  (bool (*)(test,expression)) gen_false2, /* test condition test */
168  (bool (*)(range,expression)) gen_false2, /* range arguments test */
169  (bool (*)(whileloop,expression)) gen_false2, /* whileloop condition test */
170  build_new_variable); /* new variable */
171 }
static bool indirection_test(reference ref, expression expr)
Definition: atomizer.c:155
static entity build_new_variable(entity module, basic b)
Definition: atomizer.c:147
void atomize_as_required(statement, bool(*)(reference, expression), bool(*)(call, expression), bool(*)(test, expression), bool(*)(range, expression), bool(*)(whileloop, expression), entity(*)(entity, basic))
bool gen_false2(__attribute__((unused)) gen_chunk *u1, __attribute__((unused)) void *u2)
Definition: genClib.c:2801
void normalize_all_expressions_of(void *obj)
Definition: normalize.c:668

References atomize_as_required(), build_new_variable(), gen_false2(), indirection_test(), and normalize_all_expressions_of().

Referenced by atomizer().

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

◆ reset_global_variables()

static void reset_global_variables ( )
static

reset_current_module_entity();

Definition at line 131 of file atomizer.c.

132 {
133  /* reset_current_module_entity(); */
134 
136 
138 
145 }
#define graph_undefined
Definition: graph.h:60
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
#define hash_table_undefined
Value of an undefined hash_table.
Definition: newgen_hash.h:49

References char_entities, complex_entities, double_entities, graph_undefined, hash_table_undefined, integer_entities, list_undefined, logical_entities, MemToTmp, mod_dg, and real_entities.

Referenced by atomizer().

+ Here is the caller graph for this function:

◆ rm_block_block_statement()

static statement rm_block_block_statement ( statement  stat)
static

Definition at line 199 of file atomizer.c.

200 {
202 
203  return(stat);
204 }
static void rm_db_block(statement stat)
Definition: atomizer.c:173
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362

References gen_recurse, gen_true(), rm_db_block(), and statement_domain.

Referenced by atomizer().

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

◆ rm_db_block()

static void rm_db_block ( statement  stat)
static

Definition at line 173 of file atomizer.c.

174 {
175  instruction inst1 = statement_instruction(stat);
176  if ( instruction_block_p(inst1)) {
177  list lt = instruction_block(inst1);
178  list newl = NIL;
179  MAPL (lt2, {
181  {
182  MAPL(lt3, {
183  newl=gen_nconc(newl,CONS(STATEMENT,STATEMENT(CAR(lt3)),NIL));
184  },
186  }
187  else newl = gen_nconc(newl,CONS(STATEMENT,STATEMENT(CAR(lt2)),NIL));
188  },
189  lt);
190  instruction_block(inst1) = newl;
191  ifdebug(8) {
192  //entity module = get_current_module_entity();
193  fprintf(stderr,"statement without db blocks \n");
194  print_statement(stat);
195  }
196  }
197 }
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
#define instruction_block_p(i)
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
#define ifdebug(n)
Definition: sg.c:47

References CAR, CONS, fprintf(), gen_nconc(), ifdebug, instruction_block, instruction_block_p, MAPL, NIL, print_statement(), STATEMENT, and statement_instruction.

Referenced by rm_block_block_statement().

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

Variable Documentation

◆ l_inst

list l_inst = list_undefined

FI: the following global variables are not declared STATIC because they also are used in codegen.c.

The list "first" is a truncated list from the first to the current statement (not included).

This global variable is used for the modification of the control graph, see commentaries of atomizer_of_unstructured() in this file.

Definition at line 79 of file atomizer.c.

Referenced by atomizer_of_unstructured(), and modify_blocks().

◆ MemToTmp

These lists memorize all the new created entities of each type.

– codegen.c

They are used for the declarations of the temporaries and the auxiliaries. A hash table to map temporary variables (entities) to memory variables (entities).

Definition at line 95 of file atomizer.c.

Referenced by assign_tmp_to_exp(), atomizer_of_external(), atomizer_of_intrinsic(), atomizer_of_loop(), atomizer_of_unstructured(), find_tmp_of_exp(), initialize_global_variables(), reset_global_variables(), and store_expression().

◆ mod_dg

graph mod_dg = graph_undefined
static

Dependence graph of the current module.

Definition at line 98 of file atomizer.c.

Referenced by atomizer(), initialize_global_variables(), and reset_global_variables().