PIPS
codegen.c
Go to the documentation of this file.
1 /*
2 
3  $Id: codegen.c 23065 2016-03-02 09:05:50Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 /* -- codegen.c
28  *
29  * package atomizer : Alexis Platonoff, juillet 91
30  * --
31  *
32  * Functions that generates the new instructions.
33  */
34 
35 #include "local.h"
36 
37 /* A hash table to map temporary variables (entities)
38  * to memory variables (entities).
39  */
40 extern hash_table MemToTmp;
41 
42 
43 
44 /*============================================================================*/
45 /* expression find_tmp_of_exp(expression exp): Returns the expression
46  * of the temporary in which the variable of "exp" was loaded.
47  * If "exp" is not atomic, or, if "exp" was not yet loaded, this function
48  * returns "expression_undefined".
49  *
50  * This function uses the hash table MemToTmp. For a given memory variable
51  * you may have an associated temporary. This association is built when such
52  * a variable is loaded for the first time.
53  *
54  * Called functions :
55  * _ entity_scalar_p() : ri-util/entity.c
56  * _ make_entity_expression() : ri-util/util.c
57  */
60 {
62 
64  {
65  entity exp_ent, tmp_ent;
67  if(entity_scalar_p(exp_ent))
68  {
69  tmp_ent = (entity) hash_get(MemToTmp, (char *) exp_ent);
70  if(tmp_ent != entity_undefined)
71  ret_exp = make_entity_expression(tmp_ent, NIL);
72  }
73  }
74 return(ret_exp);
75 }
76 
77 
78 
79 /*============================================================================*/
80 /* void put_stmt_in_Block(statement new_stmt, Block *cb): Puts "new_stmt"
81  * at the end of the list "cb->first".
82  *
83  * First, if "new_stmt" is the first statement generated by the statement
84  * being translated (the current statement), then the caracteritics of
85  * "new_stmt" are taken from those of the current statement.
86  *
87  * Second, "new_stmt" is added to the list of statements of "cb".
88  */
89 void put_stmt_in_Block(new_stmt, cb)
90 statement new_stmt;
91 Block *cb;
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 }
128 
129 
130 
131 /*============================================================================*/
132 /* expression assign_tmp_to_exp(expression exp, Block *cb): Produces an assign
133  * statement of "exp" in a temporary (this is a load), puts it in "cb" and
134  * returns the expression of the temporary.
135  *
136  * There are two cases:
137  * 1. "exp" is found to be a scalar variable already loaded in a
138  * temporary, then the expression of the temporary is returned.
139  *
140  * 2. otherwise, we do the following manipulations:
141  * _ Firstly, we compute a new basic of the same kind as "exp".
142  * _ Secondly, we create a new temporary with the basic found above.
143  * _ Thirdly, the new assign statement is created.
144  * _ Fourthly, this new statement is put in the current block ("cb").
145  * _ Finaly, we return the expression of the new temporary.
146  *
147  * The variable "cb" memorises the information about the block of statements
148  * that contains the expressions.
149  *
150  * Called functions :
151  * _ entity_scalar_p() : ri-util/entity.c
152  * _ make_entity_expression() : ri-util/util.c
153  * _ make_assign_statement() : ri-util/statement.c
154  */
157 Block *cb;
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 }
204 
205 
206 
207 /* We define a set of constant in order to a more generic function for the
208  * insert of the declarations of the new created variables.
209  */
210 #define INTEGER_DECL " INTEGER"
211 #define REAL_DECL " REAL"
212 #define COMPLEX_DECL " COMPLEX"
213 #define LOGICAL_DECL " LOGICAL"
214 #define DOUBLE_DECL " DOUBLE PRECISION"
215 #define CHARACTER_DECL " CHARACTER"
216 #define SPACE " "
217 #define COMA ","
218 #define NEWLINE "\n *"
219 #define ENDLINE "\nC\n"
220 #define LINE_LENGHT 68
221 #define MARGIN_LENGHT 7
222 
223 /*============================================================================*/
224 /* void insert_one_type_declaration(entity mod_entity, list var_to_decl,
225  * string type_decl):
226  * Inserts in the module "mod_entity" the declarations of the entities in the
227  * list "var_to_decl" with the type "type_decl".
228  */
229 void insert_one_type_declaration(mod_entity, var_to_decl, type_decl)
230 entity mod_entity;
231 list var_to_decl;
232 string type_decl;
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 }
274 
275 
276 
277 /*============================================================================*/
278 /* void insert_new_declarations(char *mod_name): puts in the declaration
279  * text of the module "mod_name" the declarations for the temporary, auxiliary
280  * and NLC variables.
281  *
282  * Called functions :
283  * _ local_name_to_top_level_entity() : ri-util/entity.c
284  */
285 void insert_new_declarations(char *mod_name)
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 }
320 
321 
322 /*============================================================================*/
323 /* void store_expression(expression exp, Block *cb): Removes the key of the
324  * hash table MemToTmp corresponding to the variable contained in "exp". It
325  * means that the value of this variable is no longer equal to the value of
326  * the temporary stored in MemToTmp.
327  *
328  * Note: "exp" must have a "syntax_tag" equal to "reference".
329  *
330  * Called functions :
331  * _ entity_scalar_p() : ri-util/entity.c
332  * _ make_entity_expression() : ri-util/util.c
333  * _ make_assign_statement() : ri-util/statement.c
334  */
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 }
363 
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
#define TMP_ENT
#define LINE_LENGHT
Definition: codegen.c:220
expression assign_tmp_to_exp(expression exp, Block *cb)
===========================================================================
Definition: codegen.c:155
#define DOUBLE_DECL
Definition: codegen.c:214
#define ENDLINE
Definition: codegen.c:219
#define MARGIN_LENGHT
Definition: codegen.c:221
#define CHARACTER_DECL
Definition: codegen.c:215
#define SPACE
Definition: codegen.c:216
#define COMPLEX_DECL
Definition: codegen.c:212
hash_table MemToTmp
– codegen.c
Definition: atomizer.c:95
#define NEWLINE
Definition: codegen.c:218
void put_stmt_in_Block(statement new_stmt, Block *cb)
===========================================================================
Definition: codegen.c:89
#define COMA
Definition: codegen.c:217
void insert_new_declarations(char *mod_name)
===========================================================================
Definition: codegen.c:285
void store_expression(expression exp, Block *cb)
===========================================================================
Definition: codegen.c:335
static expression find_tmp_of_exp(expression exp)
===========================================================================
Definition: codegen.c:58
#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
static statement current_stmt
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
#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
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
statement make_assign_statement(expression, expression)
Definition: statement.c:583
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:449
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
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
#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
#define STATEMENT_ORDERING_UNDEFINED
mapping.h inclusion
Definition: newgen-local.h:35
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define string_undefined
Definition: newgen_types.h:40
list double_entities
list real_entities
list complex_entities
list logical_entities
list char_entities
#define STATEMENT_NUMBER_UNDEFINED
default values
list integer_entities
Make a new variable entity which name is one letter prefix + one incrementing number.
Definition: ri-util.h:2787
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
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
code entity_code(entity e)
Definition: entity.c:1098
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
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define statement_ordering(x)
Definition: ri.h:2454
@ is_syntax_reference
Definition: ri.h:2691
#define statement_label(x)
Definition: ri.h:2450
#define entity_undefined
Definition: ri.h:2761
#define expression_undefined
Definition: ri.h:1223
#define code_decls_text(x)
Definition: ri.h:786
#define statement_comments(x)
Definition: ri.h:2456
#define statement_number(x)
Definition: ri.h:2452
#define expression_syntax(x)
Definition: ri.h:1247
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
char * strdup()
During the computation, the program has to deal with blocks of statements.
bool stmt_generated
list first
list last
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