PIPS
atomizer.h File Reference
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  Block
 During the computation, the program has to deal with blocks of statements. More...
 

Macros

#define TMP_ENT   1
 Warning! Do not modify this file that is automatically generated! More...
 
#define AUX_ENT   2
 
#define DOUBLE_PRECISION_SIZE   8
 

Functions

bool new_atomizer (char *)
 Mappings for the cumulated effects of statements. More...
 
void normalize_wp65_code (statement)
 
bool atomizer (const string)
 =========================================================================== More...
 
void atomizer_of_unstructured (unstructured)
 
void atomizer_of_statement (statement, Block *)
 =========================================================================== More...
 
void atomizer_of_block (instruction)
 =========================================================================== More...
 
void atomizer_of_test (test, Block *)
 =========================================================================== More...
 
void atomizer_of_loop (loop, Block *)
 =========================================================================== More...
 
void atomizer_of_call (call, Block *)
 =========================================================================== More...
 
void atomizer_of_intrinsic (call, Block *)
 =========================================================================== More...
 
void atomizer_of_external (call, Block *)
 =========================================================================== More...
 
list atomizer_of_expressions (list, Block *)
 =========================================================================== More...
 
expression atomizer_of_expression (expression, Block *, int)
 =========================================================================== More...
 
void atomizer_of_array_indices (expression, Block *)
 =========================================================================== More...
 
bool instruction_in_list_p (instruction, list)
 utils.c More...
 
bool nlc_linear_expression_p (expression)
 =========================================================================== More...
 
void put_stmt_in_Block (statement, Block *)
 codegen.c More...
 
expression assign_tmp_to_exp (expression, Block *)
 =========================================================================== More...
 
void insert_one_type_declaration (entity, list, string)
 =========================================================================== More...
 
void insert_new_declarations (char *)
 =========================================================================== More...
 
void store_expression (expression, Block *)
 =========================================================================== More...
 
void modify_blocks (control)
 control.c More...
 
void atom_get_blocs (control, cons **)
 
control find_control_block (control)
 =========================================================================== More...
 
void normal_expression_of_expression (expression)
 norm_exp.c More...
 
void normal_expression_of_statement (statement)
 =========================================================================== More...
 
void normal_expression_of_unstructured (unstructured)
 =========================================================================== More...
 
int get_nlc_number (entity)
 =========================================================================== More...
 
void reconfig_expression (expression)
 =========================================================================== More...
 
bool true_dependence_with_entity_p (conflict, entity)
 defs_elim.c More...
 
bool defs_elim_of_assign_call (statement, graph)
 =========================================================================== More...
 
bool defs_elim_of_statement (statement, graph)
 =========================================================================== More...
 
void defs_elim_of_unstructured (unstructured, graph)
 =========================================================================== More...
 

Variables

list l_inst
 The list "first" is a truncated list from the first to the current statement (not included). More...
 
hash_table MemToTmp
 These lists memorize all the new created entities of each type. More...
 

Macro Definition Documentation

◆ AUX_ENT

#define AUX_ENT   2

Definition at line 36 of file atomizer.h.

◆ DOUBLE_PRECISION_SIZE

#define DOUBLE_PRECISION_SIZE   8

Definition at line 37 of file atomizer.h.

◆ TMP_ENT

#define TMP_ENT   1

Warning! Do not modify this file that is automatically generated!

Modify src/Libs/atomizer/atomizer-local.h instead, to add your own modifications. header file built by cproto atomizer-local.h

Definition at line 35 of file atomizer.h.

Function Documentation

◆ assign_tmp_to_exp()

expression assign_tmp_to_exp ( expression  exp,
Block cb 
)

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

expression assign_tmp_to_exp(expression exp, Block *cb): Produces an assign statement of "exp" in a temporary (this is a load), puts it in "cb" and returns the expression of the temporary.

There are two cases:

  1. "exp" is found to be a scalar variable already loaded in a temporary, then the expression of the temporary is returned.
  2. otherwise, we do the following manipulations: _ Firstly, we compute a new basic of the same kind as "exp". _ Secondly, we create a new temporary with the basic found above. _ Thirdly, the new assign statement is created. _ Fourthly, this new statement is put in the current block ("cb"). _ Finaly, we return the expression of the new temporary.

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

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

If this expression is a scalar variable already loaded in a temporary, then it is unnecessary to loaded it again. The only thing to do is to find the temporary that was used and return it.

We compute the basic of "exp".

We create a new temporary with the basic "tmp_basic".

If "exp_ent" is a scalar variable, this temporary is placed in MemToTmp at the key "exp_ent".

We create a new expression with this temporary.

The new assign statement is created ...

... and put in the current Block.

The new temporary is returned.

Parameters
expxp
cbb

Definition at line 155 of file codegen.c.

158 {
159 expression tmp;
160 entity tmp_ent, exp_ent = entity_undefined;
161 basic tmp_basic;
162 statement new_stmt;
163 
164 /* If this expression is a scalar variable already loaded in a
165  * temporary, then it is unnecessary to loaded it again. The only
166  * thing to do is to find the temporary that was used and return it.
167  */
169  {
171  if(entity_scalar_p(exp_ent))
172  {
173  tmp = find_tmp_of_exp(exp);
174  if(tmp != expression_undefined)
175  return(tmp);
176  }
177  }
178 
179 /* We compute the basic of "exp". */
180 tmp_basic = basic_of_expression(exp);
181 
182 /* We create a new temporary with the basic "tmp_basic". */
183 tmp_ent = make_new_entity(tmp_basic, TMP_ENT);
184 
185 /* If "exp_ent" is a scalar variable, this temporary is placed in
186  * MemToTmp at the key "exp_ent".
187  */
189  if(entity_scalar_p(exp_ent))
190  hash_put(MemToTmp, (char *) exp_ent, (char *) tmp_ent);
191 
192 /* We create a new expression with this temporary. */
193 tmp = make_entity_expression(tmp_ent, NIL);
194 
195 /* The new assign statement is created ... */
196 new_stmt = make_assign_statement(tmp, exp);
197 
198 /* ... and put in the current Block. */
199 put_stmt_in_Block(new_stmt, cb);
200 
201 /* The new temporary is returned. */
202 return(tmp);
203 }
#define TMP_ENT
hash_table MemToTmp
– codegen.c
Definition: atomizer.c:95
void put_stmt_in_Block(statement new_stmt, Block *cb)
===========================================================================
Definition: codegen.c:89
static expression find_tmp_of_exp(expression exp)
===========================================================================
Definition: codegen.c:58
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
statement make_assign_statement(expression, expression)
Definition: statement.c:583
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.
Definition: hash.c:364
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
bool entity_scalar_p(entity)
The concrete type of e is a scalar type.
Definition: variable.c:1113
#define syntax_reference(x)
Definition: ri.h:2730
#define syntax_tag(x)
Definition: ri.h:2727
#define reference_variable(x)
Definition: ri.h:2326
@ is_syntax_reference
Definition: ri.h:2691
#define entity_undefined
Definition: ri.h:2761
#define expression_undefined
Definition: ri.h:1223
#define expression_syntax(x)
Definition: ri.h:1247
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207

References basic_of_expression(), entity_scalar_p(), entity_undefined, exp, expression_syntax, expression_undefined, find_tmp_of_exp(), hash_put(), is_syntax_reference, make_assign_statement(), make_entity_expression(), make_new_entity(), MemToTmp, NIL, put_stmt_in_Block(), reference_variable, syntax_reference, syntax_tag, and TMP_ENT.

Referenced by atomizer_of_expression().

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

◆ atom_get_blocs()

void atom_get_blocs ( control  ,
cons **   
)

Referenced by atomizer_of_unstructured().

+ Here is the caller graph for this function:

◆ 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 reference_indices(x)
Definition: ri.h:2328
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

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 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 value_intrinsic_p(x)
Definition: ri.h:3074
@ is_syntax_range
Definition: ri.h:2692
@ is_syntax_call
Definition: ri.h:2693
#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
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
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
#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 ( unstructured  )

◆ defs_elim_of_assign_call()

bool defs_elim_of_assign_call ( statement  assign_stmt,
graph  dg 
)

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

bool defs_elim_of_assign_call(statement assign_stmt, graph dg): returns true if "assign_stmt" is to be eliminated. It is eliminated if the lhs of this assignment verifies two conditions :

  1. it is a local variable
  2. it is not at the source of a def-use dependence, ie true dependence.

Definitions upon non local (non dynamic) variables are always kept.

Gets the vertex of the dependence graph that gives all the edges of which the assign statement is the source.

We scan all the dependences of the assign statement. If at least one true dependence is found, the statement is not removed.

Parameters
assign_stmtssign_stmt
dgg

Definition at line 136 of file defs_elim.c.

139 {
140  call assign_call;
141  expression lhs_exp;
142  entity lhs_ent;
143  vertex stmt_vertex;
144  list succs;
145  bool true_dep_found = false;
146 
148  pips_internal_error("Statement must be a CALL");
149 
150  assign_call = instruction_call(statement_instruction(assign_stmt));
151  if(! ENTITY_ASSIGN_P(call_function(assign_call)))
152  pips_internal_error("Call must be an ASSIGN");
153 
154  pips_debug(5, "begin ASSIGN : %s\n",
155  words_to_string(Words_Call(assign_call, 0, true, true)));
156 
157  lhs_exp = EXPRESSION(CAR(call_arguments(assign_call)));
159  pips_internal_error("Lhs must be a REFERENCE");
160 
162 
163 /* Definitions upon non local (non dynamic) variables are always kept. */
164  if(! entity_dynamic_p(lhs_ent) )
165  return(false);
166 
167 /* Gets the vertex of the dependence graph that gives all the edges of
168  * which the assign statement is the source.
169  */
170  stmt_vertex = get_vertex_of_statement(dg, assign_stmt);
171 
172 /* We scan all the dependences of the assign statement. If at least one
173  * true dependence is found, the statement is not removed.
174  */
175  if(stmt_vertex != vertex_undefined)
176  {
177  list confs;
178  dg_arc_label dal;
179  succs = vertex_successors(stmt_vertex);
180  for(; (succs != NIL) && (! true_dep_found) ; succs = CDR(succs))
181  {
183  confs = dg_arc_label_conflicts(dal);
184  for(; (confs != NIL) && (! true_dep_found) ; confs = CDR(confs))
185  if( true_dependence_with_entity_p(CONFLICT(CAR(confs)), lhs_ent) )
186  true_dep_found = true;
187  }
188  }
189  else
190  user_warning("defs_elim_of_assign_call",
191  "Vertex of assign stmt should not be undefined\n");
192 
193  debug(5, "defs_elim_of_assign_call", "end ASSIGN , true dep : %s\n",
194  bool_to_string(true_dep_found));
195 
196  return(! true_dep_found);
197 }
static graph dg
dg is the dependency graph ; FIXME : should not be static global ?
Definition: chains.c:124
static vertex get_vertex_of_statement(graph dg, statement stmt)
– defs_elim.c
Definition: defs_elim.c:49
bool true_dependence_with_entity_p(conflict conf, entity e)
===========================================================================
Definition: defs_elim.c:82
static bool entity_dynamic_p(entity e)
===========================================================================
Definition: defs_elim.c:114
struct _newgen_struct_dg_arc_label_ * dg_arc_label
Definition: dg.h:60
#define CONFLICT(x)
CONFLICT.
Definition: dg.h:134
#define dg_arc_label_conflicts(x)
Definition: dg.h:201
#define vertex_undefined
Definition: graph.h:128
#define successor_arc_label(x)
Definition: graph.h:116
#define vertex_successors(x)
Definition: graph.h:154
#define SUCCESSOR(x)
SUCCESSOR.
Definition: graph.h:86
#define user_warning(fn,...)
Definition: misc-local.h:262
string bool_to_string(bool)
Definition: string.c:243
list Words_Call(call obj, int precedence, bool leftmost, bool is_a_subroutine)
Definition: misc.c:2597
string words_to_string(cons *lw)
Definition: print.c:211

References bool_to_string(), call_arguments, call_function, CAR, CDR, CONFLICT, debug(), dg, dg_arc_label_conflicts, ENTITY_ASSIGN_P, entity_dynamic_p(), EXPRESSION, expression_syntax, get_vertex_of_statement(), instruction_call, instruction_tag, is_instruction_call, is_syntax_reference, NIL, pips_debug, pips_internal_error, reference_variable, statement_instruction, SUCCESSOR, successor_arc_label, syntax_reference, syntax_tag, true_dependence_with_entity_p(), user_warning, vertex_successors, vertex_undefined, Words_Call(), and words_to_string().

Referenced by defs_elim_of_statement().

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

◆ defs_elim_of_statement()

bool defs_elim_of_statement ( statement  s,
graph  dg 
)

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

bool defs_elim_of_statement(statement s, graph dg): returns true if "s" is to be eliminated. As we eliminate assign statements, only statement with call to the assign function may be eliminated.

Called_functions : _ make_empty_statement() : ri-util/statement.c

We scan all the statements of the block, and we build in the same time a new block where the statements to delete do not appear.

Parameters
dgg

Definition at line 211 of file defs_elim.c.

214 {
215  bool elim = false;
217 
218  debug(4, "defs_elim_of_statement", "begin STATEMENT\n");
219 
220  switch(instruction_tag(inst))
221  {
222  /* We scan all the statements of the block, and we build in the same time
223  * a new block where the statements to delete do not appear.
224  */
225  case is_instruction_block :
226  {
227  list new_block = NIL,
228  block = instruction_block(inst);
229  for(; block != NIL ; block = CDR(block))
230  {
233  new_block = gen_nconc(new_block, CONS(STATEMENT, stmt, NIL));
234  }
235  instruction_block(inst) = new_block;
236  break;
237  }
238  case is_instruction_test :
239  {
240  test t = instruction_test(inst);
245  break;
246  }
247  case is_instruction_loop :
248  {
249  loop l = instruction_loop(inst);
252  break;
253  }
254  case is_instruction_call :
255  {
256  call c = instruction_call(inst);
257 
258  debug(4, "defs_elim_of_statement", "Stmt CALL: %s\n",
260 
262  elim = defs_elim_of_assign_call(s, dg);
263  break;
264  }
265  case is_instruction_goto : break;
267  {
269  break;
270  }
271  default : pips_internal_error("Bad instruction tag");
272  }
273  debug(4, "defs_elim_of_statement", "end STATEMENT\n");
274 
275  return(elim);
276 }
bool defs_elim_of_statement(statement s, graph dg)
===========================================================================
Definition: defs_elim.c:211
bool defs_elim_of_assign_call(statement assign_stmt, graph dg)
===========================================================================
Definition: defs_elim.c:136
void defs_elim_of_unstructured(unstructured u, graph dg)
===========================================================================
Definition: defs_elim.c:291
#define make_empty_statement
An alias for make_empty_block_statement.

References call_function, CAR, CDR, CONS, debug(), defs_elim_of_assign_call(), defs_elim_of_statement(), defs_elim_of_unstructured(), dg, ENTITY_ASSIGN_P, entity_local_name(), gen_nconc(), 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, loop_body, make_empty_statement, NIL, pips_internal_error, STATEMENT, statement_instruction, test_false, and test_true.

Referenced by atomizer(), defs_elim_of_statement(), and defs_elim_of_unstructured().

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

◆ defs_elim_of_unstructured()

void defs_elim_of_unstructured ( unstructured  u,
graph  dg 
)

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

void defs_elim_of_unstructured(unstructured, graph dg): computes the elimination of all the definitions with no def-use dependence of an unstructured instruction.

If the statement of the control of a node of the control graph has to be eliminated, it is replaced by an empty block of statement.

Called_functions : _ make_empty_statement() : ri-util/statement.c

Parameters
dgg

Definition at line 291 of file defs_elim.c.

294 {
295  list blocs = NIL;
296 
297  debug(3, "defs_elim_of_unstructured", "begin UNSTRUCTURED\n");
298 
300  if(elim) { control_statement(c) = make_empty_statement();};},
301  unstructured_control( u ), blocs);
302 
303  gen_free_list(blocs);
304 
305  debug(3, "defs_elim_of_unstructured", "end UNSTRUCTURED\n");
306 }
#define CONTROL_MAP(ctl, code, c, list)
Macro to walk through all the controls reachable from a given control node of an unstructured.
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#define unstructured_control
After the modification in Newgen: unstructured = entry:control x exit:control we have create a macro ...

References CONTROL_MAP, control_statement, debug(), defs_elim_of_statement(), dg, gen_free_list(), make_empty_statement, NIL, and unstructured_control.

Referenced by defs_elim_of_statement().

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

◆ find_control_block()

control find_control_block ( control  c)

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

control find_control_block(control c): Returns the current control found in the static variable "cont_block".

The use of this function is: _ first, in order to initialize the static "cont_block" this function is called with the control we want to memorize. _ then, when we need to get this control, this function is called with the argument "control_undefined".

This is used by atomizer_of_statement() when we generate new statements.

Definition at line 115 of file control.c.

117 {
118 static control cont_block;
119 
120 if(c != control_undefined)
121  {
124  cont_block = CONTROL(CAR(control_predecessors(c)));
125  else
126  cont_block = control_undefined;
127  }
128 
129 return(cont_block);
130 }
#define control_predecessors(x)
Definition: ri.h:943
#define CONTROL(x)
CONTROL.
Definition: ri.h:910

References CAR, CONTROL, control_predecessors, control_statement, control_undefined, instruction_tag, is_instruction_block, and statement_instruction.

Referenced by atomizer_of_statement(), and atomizer_of_unstructured().

+ Here is the caller graph for this function:

◆ get_nlc_number()

int get_nlc_number ( entity  nlc_ent)

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

int get_nlc_number(entity nlc_ent): returns the number ending "nlc_ent" name. The local name is "NLC#", so we have to get the "#".

Parameters
nlc_entlc_ent

Definition at line 198 of file norm_exp.c.

200 {
201 const char* nlc_name = entity_local_name(nlc_ent);
202 const char* num = nlc_name+3;
203 
204 return(atoi(num));
205 }
static int num
Definition: bourdoncle.c:137

References entity_local_name(), and num.

Referenced by config_vecteur().

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

◆ insert_new_declarations()

void insert_new_declarations ( char *  mod_name)

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

void insert_new_declarations(char *mod_name): puts in the declaration text of the module "mod_name" the declarations for the temporary, auxiliary and NLC variables.

Called functions : _ local_name_to_top_level_entity() : ri-util/entity.c

We declare only variables that are not INTEGER or REAL simple precision.

Parameters
mod_nameod_name

Definition at line 285 of file codegen.c.

286 {
287  entity mod_entity;
288 
289  mod_entity = local_name_to_top_level_entity(mod_name);
290 
291  /* We declare only variables that are not INTEGER or
292  * REAL simple precision.
293  */
294 /*
295  integer_entities = gen_nreverse(integer_entities);
296  real_entities = gen_nreverse(real_entities);
297 */
302 
303 /*
304  insert_one_type_declaration(mod_entity, integer_entities, INTEGER_DECL);
305  insert_one_type_declaration(mod_entity, real_entities, REAL_DECL);
306 */
311 
312  // ??? dandling pointers to be cleaned up later
319 }
#define DOUBLE_DECL
Definition: codegen.c:214
#define CHARACTER_DECL
Definition: codegen.c:215
#define COMPLEX_DECL
Definition: codegen.c:212
#define LOGICAL_DECL
Definition: codegen.c:213
void insert_one_type_declaration(entity mod_entity, list var_to_decl, string type_decl)
===========================================================================
Definition: codegen.c:229
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
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, CHARACTER_DECL, COMPLEX_DECL, complex_entities, DOUBLE_DECL, double_entities, gen_free_list(), gen_nreverse(), insert_one_type_declaration(), integer_entities, local_name_to_top_level_entity(), LOGICAL_DECL, logical_entities, and real_entities.

+ Here is the call graph for this function:

◆ insert_one_type_declaration()

void insert_one_type_declaration ( entity  mod_entity,
list  var_to_decl,
string  type_decl 
)

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

void insert_one_type_declaration(entity mod_entity, list var_to_decl, string type_decl): Inserts in the module "mod_entity" the declarations of the entities in the list "var_to_decl" with the type "type_decl".

Type declaration.

Lenght of the declaration to insert.

If the line is to long ..., we begin a new line!!

We separate the variables between comas.

Parameters
mod_entityod_entity
var_to_declar_to_decl
type_declype_decl

Definition at line 229 of file codegen.c.

233 {
234 string new_decls;
235 code mod_code;
236 list l;
237 int counter = strlen(type_decl);
238 
239 if(var_to_decl != NIL)
240  {
241  /* Type declaration. */
242  new_decls = strdup(concatenate(type_decl, (char *) NULL));
243  for(l = var_to_decl; l != NIL;)
244  {
245  entity e = ENTITY(CAR(l));
246 
247  /* Lenght of the declaration to insert. */
248  int decl_len = strlen(SPACE) + strlen(COMA) + strlen(entity_local_name(e));
249 
250  /* If the line is to long ..., we begin a new line!! */
251  if( (counter + decl_len) > LINE_LENGHT)
252  {
253  counter = MARGIN_LENGHT;
254  new_decls = strdup(concatenate(new_decls, NEWLINE, (char *) NULL));
255  }
256  new_decls = strdup(concatenate(new_decls, SPACE,
257  entity_local_name(e), (char *) NULL));
258  l = CDR(l);
259 
260  /* We separate the variables between comas. */
261  if(l != NIL)
262  new_decls = strdup(concatenate(new_decls, COMA, (char *) NULL));
263 
264  counter += decl_len;
265  }
266 
267  new_decls = strdup(concatenate(new_decls, ENDLINE, (char *) NULL));
268 
269  mod_code = entity_code(mod_entity);
270  code_decls_text(mod_code) = strdup(concatenate(code_decls_text(mod_code),
271  new_decls, (char *) NULL));
272  }
273 }
#define LINE_LENGHT
Definition: codegen.c:220
#define ENDLINE
Definition: codegen.c:219
#define MARGIN_LENGHT
Definition: codegen.c:221
#define SPACE
Definition: codegen.c:216
#define NEWLINE
Definition: codegen.c:218
#define COMA
Definition: codegen.c:217
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
code entity_code(entity e)
Definition: entity.c:1098
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define code_decls_text(x)
Definition: ri.h:786

References CAR, CDR, code_decls_text, COMA, concatenate(), ENDLINE, ENTITY, entity_code(), entity_local_name(), LINE_LENGHT, MARGIN_LENGHT, NEWLINE, NIL, SPACE, and strdup().

Referenced by insert_new_declarations().

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

◆ instruction_in_list_p()

bool instruction_in_list_p ( instruction  inst,
list  l 
)

utils.c

utils.c

bool instruction_in_list_p(instruction inst, list l): Returns true if "inst" is in "l".

Note: "l" must be a list of instructions.

Parameters
instnst

Definition at line 50 of file utils.c.

53 {
54 bool not_found = true;
55 
56 while((not_found) && (l != NIL))
57  {
58  instruction current_inst = INSTRUCTION(CAR(l));
59  if (inst == current_inst)
60  not_found = false;
61  else
62  l = CDR(l);
63  }
64 return (! not_found);
65 }
#define INSTRUCTION(x)
INSTRUCTION.
Definition: ri.h:1448

References CAR, CDR, INSTRUCTION, and NIL.

Referenced by modify_blocks().

+ Here is the caller graph for this function:

◆ modify_blocks()

void modify_blocks ( control  c)

control.c

control.c

package atomizer : Alexis Platonoff, juillet 91

Functions for the manipulations and modifications of the control graph. =========================================================================== void modify_blocks(control c): Adds a node to the control graph when the statement of "c" is not an "instruction_block".

This node is added just before "c". "c" predecessor became the new node. The latter's predecessors are those of "c", its successor is "c".

"l_inst" keep the reference to the instructions for which a new node is added. It is a global variable that will be used when we will generate new statements (see atomizer_of_statement(), in atomizer.c).

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

Definition at line 51 of file control.c.

53 {
54 extern list l_inst;
55 
56 control nc;
58 
60  {
61  if (! instruction_in_list_p(inst, l_inst))
62  {
65 
68 
70 
71  l_inst = CONS(INSTRUCTION, inst, l_inst);
72  }
73  }
74 }
control make_control(statement a1, list a2, list a3)
Definition: ri.c:523
list l_inst
The list "first" is a truncated list from the first to the current statement (not included).
Definition: atomizer.h:87
bool instruction_in_list_p(instruction, list)
utils.c
Definition: utils.c:50
#define control_successors(x)
Definition: ri.h:945

References CONS, CONTROL, control_predecessors, control_statement, control_successors, INSTRUCTION, instruction_in_list_p(), instruction_tag, is_instruction_block, l_inst, make_control(), make_empty_statement, NIL, and statement_instruction.

Referenced by atom_get_blocs().

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

◆ new_atomizer()

bool new_atomizer ( char *  mod_name)

Mappings for the cumulated effects of statements.

extern statement_mapping cumulated_effects_map; cproto-generated files new_atomizer.c

get the resources

Now do the job

Reorder the module, because new statements have been added

update/release resources

Parameters
mod_nameod_name

Definition at line 164 of file new_atomizer.c.

165 {
166  /* get the resources */
169  set_cumulated_rw_effects((statement_effects)db_get_memory_resource(DBR_CUMULATED_EFFECTS, mod_name, true));
170  debug_on("NEW_ATOMIZER_DEBUG_LEVEL");
171 
172 
173  /* Now do the job */
175 
176  /* Reorder the module, because new statements have been added */
180 
181  /* update/release resources */
185  debug_off();
186 
187  return true;
188 }
bool clean_up_sequences(statement s)
Recursively clean up the statement sequences by fusing them if possible and by removing useless one.
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
static void atomize_statement(statement stat)
This function is called for all statements in the code.
Definition: new_atomizer.c:146
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362

References atomize_statement(), clean_up_sequences(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, gen_recurse, gen_true(), get_current_module_statement(), module_name_to_entity(), module_reorder(), reset_cumulated_rw_effects(), reset_current_module_entity(), reset_current_module_statement(), set_cumulated_rw_effects(), set_current_module_entity(), set_current_module_statement(), and statement_domain.

+ Here is the call graph for this function:

◆ nlc_linear_expression_p()

bool nlc_linear_expression_p ( expression  exp)

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

bool nlc_linear_expression_p(expression exp): returns true if "exp" is an integer linear expression with only NLCs variables.

NLC means Normalized Loop Counter.

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

We unnormalize the expression, otherwise, it causes an error when we normalize an expression with sub-expressions already normalized. (cf. NormalizedExpression() in normalize/normalize.c).

This unnormalization is done recursively upon all the sub-expressions of "exp".

Parameters
expxp

Definition at line 78 of file utils.c.

80 {
81 Pvecteur vect;
82 bool ONLY_NLCs;
83 
84 pips_debug(7, "exp : %s\n", expression_to_string(exp));
85 
87  ONLY_NLCs = false;
88 else
89  {
91  ONLY_NLCs = true;
92 
93  for(; !VECTEUR_NUL_P(vect) && ONLY_NLCs ; vect = vect->succ)
94  {
95  entity var = (entity) vect->var;
96 
97  if( ! term_cst(vect) )
98  if( ! (ENTITY_NLC_P(var)) )
99  ONLY_NLCs = false;
100  }
101  }
102 
103 /* We unnormalize the expression, otherwise, it causes an error when we
104  * normalize an expression with sub-expressions already normalized.
105  * (cf. NormalizedExpression() in normalize/normalize.c).
106  *
107  * This unnormalization is done recursively upon all the sub-expressions of
108  * "exp".
109  */
111 
112 debug(7, "nlc_linear_expression_p", " result : %d\n", ONLY_NLCs);
113 
114 return(ONLY_NLCs);
115 }
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
#define ENTITY_NLC_P(e)
Definition: utils.c:39
void unnormalize_expression(void *st)
void unnormalize_expression(expression exp): puts all the normalized field of expressions in "st" to ...
Definition: normalize.c:452
#define NORMALIZE_EXPRESSION(e)
#define normalized_tag(x)
Definition: ri.h:1778
#define expression_normalized(x)
Definition: ri.h:1249
#define normalized_linear(x)
Definition: ri.h:1781
@ is_normalized_complex
Definition: ri.h:1761
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
Variable var
Definition: vecteur-local.h:90
struct Svecteur * succ
Definition: vecteur-local.h:92
struct Svecteur * Pvecteur
#define VECTEUR_NUL_P(v)
#define term_cst(varval)

References debug(), ENTITY_NLC_P, exp, expression_normalized, expression_to_string(), is_normalized_complex, NORMALIZE_EXPRESSION, normalized_linear, normalized_tag, pips_debug, Svecteur::succ, term_cst, unnormalize_expression(), Svecteur::var, and VECTEUR_NUL_P.

Referenced by atomizer_of_expression(), and atomizer_of_intrinsic().

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

◆ normal_expression_of_expression()

void normal_expression_of_expression ( expression  exp)

norm_exp.c

norm_exp.c

void normal_expression_of_expression(expression exp): normalizes "exp".

There are three cases:

  1. "exp" is a call to an intrinsic or external function.
  2. "exp" is a reference.
  3. "exp" is a range

In the case (1), if "exp" is linear (ie normalized), we call reconfig_expression(); it computes the normalization of "exp" with its Pvecteur. If "exp" is not integer linear, this function is called recursively upon the arguments of the call.

In case (2), we call this function upon each of the indices of "exp".

In case (3), we do nothing. Such a case may occur with a range argument in a call to a write or read procedure.

Parameters
expxp

Definition at line 72 of file norm_exp.c.

74 {
76 if(syntax_tag(sy) == is_syntax_call)
77  {
78  call c = syntax_call(sy);
79  if(! call_constant_p(c))
80  {
83  {
84  pips_debug(5, "Expression Linear : %s\n", expression_to_string(exp));
85 
87  }
88  else
89  {
90  list args = call_arguments(c);
91 
92  pips_debug(5, "Expression Complex : %s\n",
94 
95  for(; args != NIL; args = CDR(args))
97  }
99  }
100  }
101 else if(syntax_tag(sy) == is_syntax_reference)
102  {
104  list inds = reference_indices(ref);
105  for(; inds != NIL; inds = CDR(inds))
107  }
108 else if(syntax_tag(sy) == is_syntax_range)
109  {
110  pips_debug(6, "Expression Range : %s\n",
112  }
113 else
114  pips_internal_error("Bad expression tag");
115 }
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
void normal_expression_of_expression(expression exp)
===========================================================================
Definition: norm_exp.c:72
void reconfig_expression(expression exp)
===========================================================================
Definition: norm_exp.c:334
#define normalized_undefined
Definition: ri.h:1745
@ is_normalized_linear
Definition: ri.h:1760

References call_arguments, call_constant_p, CAR, CDR, exp, EXPRESSION, expression_normalized, expression_syntax, expression_to_string(), is_normalized_linear, is_syntax_call, is_syntax_range, is_syntax_reference, NIL, normal_expression_of_expression(), NORMALIZE_EXPRESSION, normalized_tag, normalized_undefined, pips_debug, pips_internal_error, reconfig_expression(), ref, reference_indices, syntax_call, syntax_reference, and syntax_tag.

Referenced by normal_expression_of_expression(), and normal_expression_of_statement().

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

◆ normal_expression_of_statement()

void normal_expression_of_statement ( statement  s)

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

void normal_expression_of_statement(statement s): normalizes the expressions contained in "s".

Definition at line 123 of file norm_exp.c.

125 {
127 
128 debug(4, "normal_expression_of_statement", "begin STATEMENT\n");
129 
130 switch(instruction_tag(inst))
131  {
132  case is_instruction_block :
133  { list block = instruction_block(inst);
134  for(; block != NIL ; block = CDR(block))
136  break; }
137  case is_instruction_test :
138  { test t = instruction_test(inst);
142  break; }
143  case is_instruction_loop :
144  { loop l = instruction_loop(inst);
145  range lr = loop_range(l);
150  break; }
151  case is_instruction_call :
152  { call c = instruction_call(inst);
153  list args = call_arguments(c);
154 
155  debug(4, "normal_expression_of_statement", "Stmt CALL: %s\n",
157 
158  for(; args != NIL; args = CDR(args))
160  break; }
161  case is_instruction_goto : break;
164  break; }
165  default : pips_internal_error("Bad instruction tag");
166  }
167 debug(4, "normal_expression_of_statement", "end STATEMENT\n");
168 }
void normal_expression_of_statement(statement s)
===========================================================================
Definition: norm_exp.c:123
void normal_expression_of_unstructured(unstructured u)
===========================================================================
Definition: norm_exp.c:176

References call_arguments, call_function, CAR, CDR, debug(), entity_local_name(), EXPRESSION, 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, loop_body, loop_range, NIL, normal_expression_of_expression(), normal_expression_of_statement(), normal_expression_of_unstructured(), pips_internal_error, range_increment, range_lower, range_upper, STATEMENT, statement_instruction, test_condition, test_false, and test_true.

Referenced by atomizer(), normal_expression_of_statement(), and normal_expression_of_unstructured().

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

◆ normal_expression_of_unstructured()

void normal_expression_of_unstructured ( unstructured  u)

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

void normal_expression_of_unstructured(unstructured u): normalizes the expressions of an unstructured instruction "u".

Definition at line 176 of file norm_exp.c.

178 {
179 list blocs = NIL;
180 
181 debug(3, "normal_expression_of_unstructured", "begin UNSTRUCTURED\n");
182 
184  unstructured_control( u ), blocs);
185 
186 gen_free_list(blocs);
187 
188 debug(3, "normal_expression_of_unstructured", "end UNSTRUCTURED\n");
189 }

References CONTROL_MAP, control_statement, debug(), gen_free_list(), NIL, normal_expression_of_statement(), and unstructured_control.

Referenced by normal_expression_of_statement().

+ 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:

◆ put_stmt_in_Block()

void put_stmt_in_Block ( statement  new_stmt,
Block cb 
)

codegen.c

codegen.c

void put_stmt_in_Block(statement new_stmt, Block *cb): Puts "new_stmt" at the end of the list "cb->first".

First, if "new_stmt" is the first statement generated by the statement being translated (the current statement), then the caracteritics of "new_stmt" are taken from those of the current statement.

Second, "new_stmt" is added to the list of statements of "cb".

The current statement is the first element of the list "cb->last".

"stmt_generated" is false if the current statement has not produced any statement yet, in which case the new statement gets the "label", "number", "ordering" and "comments" (cf. RI) of the current statement.

The new statement gets the caracteristic of the current statement, while the latter gets the caracteristics of the new statement.

The current statement has, now, generated at least one statement.

The new statement is put just before the current statement in the block. Thus, it is put in last position in the list "cb->first".

Parameters
new_stmtew_stmt
cbb

Definition at line 89 of file codegen.c.

92 {
94 
95 /* The current statement is the first element of the list "cb->last". */
97 
98 /* "stmt_generated" is false if the current statement has not produced
99  * any statement yet, in which case the new statement gets the "label",
100  * "number", "ordering" and "comments" (cf. RI) of the current statement.
101  */
102 if (! cb->stmt_generated)
103  {
104  entity new_label;
105  /* The new statement gets the caracteristic of the current statement,
106  * while the latter gets the caracteristics of the new statement.
107  */
108  new_label = statement_label(new_stmt);
113 
114  statement_label(current_stmt) = new_label;
118 
119  /* The current statement has, now, generated at least one statement. */
120  cb->stmt_generated = true;
121  }
122 
123 /* The new statement is put just before the current statement in the block.
124  * Thus, it is put in last position in the list "cb->first".
125  */
126 cb->first = gen_nconc(cb->first, CONS(STATEMENT, new_stmt, NIL));
127 }
static statement current_stmt
#define STATEMENT_ORDERING_UNDEFINED
mapping.h inclusion
Definition: newgen-local.h:35
#define string_undefined
Definition: newgen_types.h:40
#define STATEMENT_NUMBER_UNDEFINED
default values
#define statement_ordering(x)
Definition: ri.h:2454
#define statement_label(x)
Definition: ri.h:2450
#define statement_comments(x)
Definition: ri.h:2456
#define statement_number(x)
Definition: ri.h:2452

References CAR, CONS, current_stmt, Block::first, gen_nconc(), Block::last, NIL, STATEMENT, statement_comments, statement_label, statement_number, STATEMENT_NUMBER_UNDEFINED, statement_ordering, STATEMENT_ORDERING_UNDEFINED, Block::stmt_generated, and string_undefined.

Referenced by assign_tmp_to_exp(), and atomizer_of_external().

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

◆ reconfig_expression()

void reconfig_expression ( expression  exp)

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

void reconfig_expression(expression exp): "exp" is reordered so as to gather all the NLCs in the innermost parenthesis. More, the NLC of the inner loop is in the innermost parenthesis with the TCST (constant term). For example, if we have: (4*S + ( NLC1 + ((T + 7) + 3*NLC2))) + C) + 8*NLC3 it is reordered in: 4*S + (T + (C + (8*NLC1 + (3*NLC2 + (NLC3 + 7)))))

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

We configurate the Pvecteur of "exp".

We build a new expression with the configurated Pvecteur.

We change the syntax of "exp".

Parameters
expxp

Definition at line 334 of file norm_exp.c.

336 {
337 Pvecteur vect, new_vect;
340 expression new_exp;
341 
343  return;
345  return;
347  return;
348 
349 vect = (Pvecteur) normalized_linear(nor);
350 
351 /* We configurate the Pvecteur of "exp". */
352 new_vect = config_vecteur(vect);
353 
354 /* We build a new expression with the configurated Pvecteur. */
355 new_exp = Pvecteur_to_expression(new_vect);
356 
357 /* We change the syntax of "exp". */
358 if(new_exp != expression_undefined)
360 }
static Pvecteur config_vecteur(Pvecteur Vvar)
===========================================================================
Definition: norm_exp.c:225
expression Pvecteur_to_expression(Pvecteur vect)
AP, sep 25th 95 : some usefull functions moved from static_controlize/utils.c.
Definition: expression.c:1825

References call_constant_p, config_vecteur(), exp, expression_syntax, expression_undefined, is_normalized_linear, is_syntax_reference, NORMALIZE_EXPRESSION, normalized_linear, normalized_tag, Pvecteur_to_expression(), syntax_call, and syntax_tag.

Referenced by normal_expression_of_expression().

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

◆ store_expression()

void store_expression ( expression  exp,
Block cb 
)

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

void store_expression(expression exp, Block *cb): Removes the key of the hash table MemToTmp corresponding to the variable contained in "exp". It means that the value of this variable is no longer equal to the value of the temporary stored in MemToTmp.

Note: "exp" must have a "syntax_tag" equal to "reference".

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

entity tmp_ent;

Parameters
expxp
cbb

Definition at line 335 of file codegen.c.

336 {
337  entity ent;
338 
339  pips_assert("true", cb==cb);
340 
342  pips_user_error("Expression is not a reference");
343 
345  if(entity_scalar_p(ent))
346  {
347  /* entity tmp_ent; */
348 
349  (void) hash_del(MemToTmp, (char *) ent);
350 
351  /*
352  tmp_ent = (entity) hash_get(MemToTmp, (char *) ent);
353  if(tmp_ent != entity_undefined)
354  {
355  expression tmp;
356  tmp = make_entity_expression(tmp_ent, NIL);
357  put_stmt_in_Block(make_assign_statement(exp, tmp), cb);
358  (void) hash_del(MemToTmp, (char *) ent);
359  }
360  */
361  }
362 }
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_user_error
Definition: misc-local.h:147

References entity_scalar_p(), exp, expression_syntax, hash_del(), is_syntax_reference, MemToTmp, pips_assert, pips_user_error, reference_variable, syntax_reference, and syntax_tag.

+ Here is the call graph for this function:

◆ true_dependence_with_entity_p()

bool true_dependence_with_entity_p ( conflict  conf,
entity  e 
)

defs_elim.c

defs_elim.c

bool true_dependence_with_entity_p(conflict conf, entity e): returns TRUE if the conflict "conf" is a true dependence upon the entity "e".

A true dependence is a conflict with a Write at the "source" and a Read at the "sink".

called functions : _ effect_entity() : ri-util/util.c _ same_entity_p() : ri-util/util.c

Parameters
confonf

Definition at line 82 of file defs_elim.c.

85 {
86  effect source_eff, sink_eff;
87  entity source_ent, sink_ent;
88 
89  source_eff = conflict_source(conf);
90  sink_eff = conflict_sink(conf);
91  source_ent = effect_entity(source_eff);
92  sink_ent = effect_entity(sink_eff);
93 
94  pips_debug(6, " CONFLICT : %s --> %s\n",
95  effect_to_string(source_eff),
96  effect_to_string(sink_eff));
97 
98  if(! same_entity_p(source_ent, sink_ent))
99  pips_internal_error("Source and sink entities must be equal");
100 
101  return( same_entity_p(e, source_ent) &&
102  (action_tag(effect_action(source_eff)) == is_action_write) &&
103  (action_tag(effect_action(sink_eff)) == is_action_read) );
104 }
#define conflict_sink(x)
Definition: dg.h:167
#define conflict_source(x)
Definition: dg.h:165
string effect_to_string(effect)
entity effect_entity(effect)
cproto-generated files
Definition: effects.c:52
@ is_action_read
Definition: effects.h:292
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321

References action_tag, conflict_sink, conflict_source, effect_action, effect_entity(), effect_to_string(), is_action_read, is_action_write, pips_debug, pips_internal_error, and same_entity_p().

Referenced by defs_elim_of_assign_call().

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

Variable Documentation

◆ l_inst

list l_inst
extern

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

atomizer.c

The list "last" is a truncated list from the current statement (included) to the last. The union of "first" and "last" is equal to the entire block.

The bool "stmt_generated" says if the current statement has: _ true : already generated statements. _ false : not generated statements.

Thus, when the current statement generates a new statement it is put at the end of the list "first" (just before the current statement). The current statement gives its caracteristics to the new one if the bool "stmt_generated" is false; this allows to keep these caracteristics at the first statement of the list generated by the translation of the current statement. The caracteristics of a statement are its "label", "number", "ordering" and "comments" (cf. RI). This global variable is used for the modification of the control graph, see commentaries of atomizer_of_unstructured() in atomizer.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 87 of file atomizer.h.

Referenced by atomizer_of_unstructured().

◆ MemToTmp

hash_table MemToTmp
extern

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

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.