PIPS
fortran90.c File Reference
#include <stdio.h>
#include "linear.h"
#include "genC.h"
#include "text.h"
#include "text-util.h"
#include "ri.h"
#include "misc.h"
#include "ri-util.h"
#include "prettyprint.h"
+ Include dependency graph for fortran90.c:

Go to the source code of this file.

Functions

static statement body_to_assignment_statement (statement b)
 The tests necessary to check the underlying assumptions have been performed in text_loop(): b is either an assignment or a sequence with only one statement which is an assignment. More...
 
text text_loop_90 (entity module, const char *label, int margin, loop obj, int n)
 Generate range subscript for simple loop with only one assignment. More...
 
static expression expand_call (expression e, entity f, list args)
 Only one call site for expand_call(). More...
 
expression expand_reference (syntax s, expression e, entity i, range r)
 A reference cannot always be expanded. More...
 
expression expand_expression (e, i, r)
 Expression with a non-expandable sub-expression, e.g. More...
 

Variables

static set vectors
 Prettyprint one FORTRAN 90 loop as an array expression. More...
 

Function Documentation

◆ body_to_assignment_statement()

static statement body_to_assignment_statement ( statement  b)
static

The tests necessary to check the underlying assumptions have been performed in text_loop(): b is either an assignment or a sequence with only one statement which is an assignment.

because of the input assumptions

Definition at line 61 of file fortran90.c.

62 {
65 
66  if(instruction_sequence_p(bi)) {
68  s = STATEMENT(CAR(sl));
69  }
70  else /* because of the input assumptions */
71  s = b;
72 
73  return s;
74 }
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define instruction_sequence_p(x)
Definition: ri.h:1512
#define sequence_statements(x)
Definition: ri.h:2360
#define instruction_sequence(x)
Definition: ri.h:1514
#define statement_instruction(x)
Definition: ri.h:2458
#define statement_undefined
Definition: ri.h:2419
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References CAR, instruction_sequence, instruction_sequence_p, sequence_statements, STATEMENT, statement_instruction, and statement_undefined.

Referenced by text_loop_90().

+ Here is the caller graph for this function:

◆ expand_call()

static expression expand_call ( expression  e,
entity  f,
list  args 
)
static

Only one call site for expand_call().

All args have been newly allocated there and are re-used here to build new_e, Or they are freed without forgetting the references thru set "vectors". There is no sharing between e and new_e.

strcmp( entity_local_name( f ), DIVIDE_OPERATOR_NAME ) == 0 ||

FI: Sharing thru args? Yes, but see above.

No sharing between e and new_e

Definition at line 145 of file fortran90.c.

146 {
148  bool vector_op =
149  (strcmp( entity_local_name( f ), PLUS_OPERATOR_NAME ) == 0 ||
150  strcmp( entity_local_name( f ), MINUS_OPERATOR_NAME ) == 0 ||
151  /* strcmp( entity_local_name( f ), DIVIDE_OPERATOR_NAME ) == 0 || */
152  strcmp( entity_local_name( f ), MULTIPLY_OPERATOR_NAME ) == 0 ) ;
153 
154  if( !vector_op ) {
155  /* FI: Sharing thru args? Yes, but see above. */
156  bool vectorp = false;
158  make_call( f, args )),
160  MAP(EXPRESSION, arg, {
161  vectorp |= set_belong_p( vectors, (char *)arg );
162  }, args);
163 
164  if(vectorp)
165  set_add_element( vectors, vectors, (char *)new_e ) ;
166  }
167  else {
168  expression lhs = EXPRESSION(CAR(args)) ;
169  expression rhs = EXPRESSION(CAR(CDR(args))) ;
170  syntax ls = expression_syntax( lhs ) ;
171  syntax rs = expression_syntax( rhs ) ;
172 
173  if(set_belong_p( vectors, (char *)lhs ) &&
174  set_belong_p( vectors, (char *)rhs )) {
175  if( syntax_range_p( ls ) && syntax_range_p( rs )) {
176  range rl = syntax_range( ls ) ;
177  range rr = syntax_range( rs ) ;
178 
179  new_e = update_range(f, rl,
180  range_lower(rr), range_upper(rr),
181  range_increment(rr), true) ;
182  }
183  else {
184  new_e = MakeBinaryCall( f, lhs, rhs ) ;
185  }
186  set_add_element( vectors, vectors, (char *)new_e ) ;
187  }
188  else if( set_belong_p( vectors, (char *)lhs )) {
189  if( syntax_range_p( ls )) {
190  range rl = syntax_range( ls ) ;
191 
192  new_e = update_range(f, rl, rhs, rhs, int_to_expression(1), true) ;
193  }
194  else {
195  new_e = MakeBinaryCall( f, lhs, rhs ) ;
196  }
197  set_add_element( vectors, vectors, (char *)new_e ) ;
198  }
199  else if( set_belong_p( vectors, (char *)rhs )) {
200  if( syntax_range_p( rs )) {
201  range rr = syntax_range( rs ) ;
202 
203  new_e = update_range(f, rr, lhs, lhs, int_to_expression(1), false) ;
204  }
205  else {
206  new_e = MakeBinaryCall( f, lhs, rhs ) ;
207  }
208  set_add_element(vectors, vectors, (char *) new_e);
209  }
210  else {
211  /* No sharing between e and new_e */
212  new_e = copy_expression(e);
213  }
214  }
215  return new_e;
216 }
call make_call(entity a1, list a2)
Definition: ri.c:269
expression make_expression(syntax a1, normalized a2)
Definition: ri.c:886
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
syntax make_syntax(enum syntax_utype tag, void *val)
Definition: ri.c:2491
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
bool set_belong_p(const set, const void *)
Definition: set.c:194
set set_add_element(set, const set, const void *)
Definition: set.c:152
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
static set vectors
Prettyprint one FORTRAN 90 loop as an array expression.
Definition: fortran90.c:56
#define MINUS_OPERATOR_NAME
#define PLUS_OPERATOR_NAME
#define MULTIPLY_OPERATOR_NAME
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
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188
expression update_range(f, r, expression lw, expression up, expression in, bool left)
Prettyprint one FORTRAN 90 loop as an array expression.
Definition: fortran90.c:61
#define normalized_undefined
Definition: ri.h:1745
#define range_upper(x)
Definition: ri.h:2290
#define syntax_range(x)
Definition: ri.h:2733
@ is_syntax_call
Definition: ri.h:2693
#define range_increment(x)
Definition: ri.h:2292
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define expression_undefined
Definition: ri.h:1223
#define range_lower(x)
Definition: ri.h:2288
#define syntax_range_p(x)
Definition: ri.h:2731
#define expression_syntax(x)
Definition: ri.h:1247

References CAR, CDR, copy_expression(), entity_local_name(), EXPRESSION, expression_syntax, expression_undefined, f(), int_to_expression(), is_syntax_call, make_call(), make_expression(), make_syntax(), MakeBinaryCall(), MAP, MINUS_OPERATOR_NAME, MULTIPLY_OPERATOR_NAME, normalized_undefined, PLUS_OPERATOR_NAME, range_increment, range_lower, range_upper, set_add_element(), set_belong_p(), syntax_range, syntax_range_p, update_range(), and vectors.

Referenced by expand_expression().

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

◆ expand_expression()

expression expand_expression ( ,
,
 
)

Expression with a non-expandable sub-expression, e.g.

a non-expandable reference, cannot be expanded.

Arguments are not (should not be) shared with the returned expression.

FI: I do not know why dim is computed. Old cut-and-paste from expand_reference()?

Definition at line 286 of file fortran90.c.

290 {
291  syntax s = expression_syntax( e ) ;
293 
294  switch(syntax_tag( s ))
295  {
296  case is_syntax_reference:
297  new_e = expand_reference( s, e, i, r);
298  break;
299  case is_syntax_call: {
300  call c = syntax_call( s ) ;
301  cons *new_args = NIL ;
302  entity f = call_function( c ) ;
303  int dim = 0 ;
304 
305  MAPL( args, {
306  expression arg = EXPRESSION( CAR( args )) ;
307 
308  new_e = expand_expression( arg, i, r ) ;
309 
310  if(expression_undefined_p(new_e)) {
311  return new_e;
312  }
313 
314  /* FI: I do not know why dim is computed. Old cut-and-paste
315  from expand_reference()? */
316  if(set_belong_p( vectors, (char *)new_e )) {
317  dim++;
318  }
319 
320  new_args = CONS(EXPRESSION, new_e, new_args ) ;
321  }, call_arguments( c )) ;
322 
323  new_e = expand_call(e, f, gen_nreverse(new_args));
324  break;
325  }
326  case is_syntax_range:
327  pips_internal_error("Range expansion not implemented" ) ;
328  default:
329  pips_internal_error("unexpected syntax tag (%d)",
330  syntax_tag(s));
331  }
332 
333  return new_e;
334 }
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
#define MAPL(_map_list_cp, _code, _l)
Apply some code on the addresses of all the elements of a list.
Definition: newgen_list.h:203
#define pips_internal_error
Definition: misc-local.h:149
expression expand_expression(e, i, r)
Expression with a non-expandable sub-expression, e.g.
Definition: fortran90.c:286
expression expand_reference(syntax s, expression e, entity i, range r)
A reference cannot always be expanded.
Definition: fortran90.c:225
static expression expand_call(expression e, entity f, list args)
Only one call site for expand_call().
Definition: fortran90.c:145
#define syntax_tag(x)
Definition: ri.h:2727
#define call_function(x)
Definition: ri.h:709
@ is_syntax_range
Definition: ri.h:2692
@ is_syntax_reference
Definition: ri.h:2691
#define syntax_call(x)
Definition: ri.h:2736
#define expression_undefined_p(x)
Definition: ri.h:1224
#define call_arguments(x)
Definition: ri.h:711

References call_arguments, call_function, CAR, CONS, expand_call(), expand_reference(), EXPRESSION, expression_syntax, expression_undefined, expression_undefined_p, f(), gen_nreverse(), is_syntax_call, is_syntax_range, is_syntax_reference, MAPL, NIL, pips_internal_error, set_belong_p(), syntax_call, syntax_tag, and vectors.

Referenced by expand_reference(), and text_loop_90().

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

◆ expand_reference()

expression expand_reference ( syntax  s,
expression  e,
entity  i,
range  r 
)

A reference cannot always be expanded.

Subscript expression coupling as in A(I,I) prevent expansion and an undefined expression is returned. Non-affine expressions such as A(I**2) cannot be transformed into triplets but can be tranformed into implicit DO vectors.

Arguments s, e, i and r should not be shared with the returned expression.

expand occurence of loop index

expand 1 subscript expression or fail or leave unexpanded

If dim is greater than 1, subscript expressions are coupled as in A(I,I+1).

new_args should be freed

Just the spine or more?

Definition at line 225 of file fortran90.c.

226 {
227  reference rf = syntax_reference(s) ;
229 
230  if( same_entity_p( reference_variable( rf ), i )) {
231  /* expand occurence of loop index */
233  new_e = make_expression(new_s, normalized_undefined) ;
234  set_add_element( vectors, vectors, (char *) new_e ) ;
235  }
236  else {
237  /* expand 1 subscript expression or fail or leave unexpanded */
238  int dim = 0 ;
239  cons *new_args = NIL ;
240  reference new_r ;
241 
242  MAPL( args, {
243  expression arg = EXPRESSION( CAR( args )) ;
244 
245  new_e = expand_expression( arg, i, r ) ;
246 
247  if(expression_undefined_p(new_e))
248  return new_e;
249 
250  if(set_belong_p( vectors, (char *)new_e ))
251  dim++;
252 
253  new_args = CONS(EXPRESSION, new_e, new_args ) ;
254  }, reference_indices( rf )) ;
255 
256  if( dim==1 ) {
258  gen_nreverse(new_args)) ;
261  set_add_element( vectors, vectors, (char *)new_e ) ;
262  }
263  else if(dim > 1) {
264  /* If dim is greater than 1, subscript expressions are coupled
265  * as in A(I,I+1).
266  */
267  /* new_args should be freed */
268  new_e = expression_undefined;
269  }
270  else {
271  /* Just the spine or more? */
272  gen_free_list(new_args);
273  new_e = copy_expression(e);
274  }
275  }
276  return new_e;
277 }
range copy_range(range p)
RANGE.
Definition: ri.c:2005
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
#define syntax_reference(x)
Definition: ri.h:2730
#define reference_variable(x)
Definition: ri.h:2326
#define reference_indices(x)
Definition: ri.h:2328

References CAR, CONS, copy_expression(), copy_range(), expand_expression(), EXPRESSION, expression_undefined, expression_undefined_p, gen_free_list(), gen_nreverse(), is_syntax_range, is_syntax_reference, make_expression(), make_reference(), make_syntax(), MAPL, NIL, normalized_undefined, reference_indices, reference_variable, same_entity_p(), set_add_element(), set_belong_p(), syntax_reference, and vectors.

Referenced by expand_expression().

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

◆ text_loop_90()

text text_loop_90 ( entity  module,
const char *  label,
int  margin,
loop  obj,
int  n 
)

Generate range subscript for simple loop with only one assignment.

fortran90.c

text_loop_90() only is called if the loop is parallel and if its body is a unique assignment statement or a list containing a unique assignment.

statement_ordering must be initialized too to avoid a prettyprinter warning

FI: Although new_s has been converted to text, it cannot always be freed. I do not know which part of new_s is reused in the result of text_statement() or somewhere else... Found with valgrind and validation case Prettyprint/aa01.tpips

No legal vector form has been found

Parameters
moduleodule
labelabel
marginargin
objbj

Definition at line 77 of file fortran90.c.

78 {
79  /* text_loop_90() only is called if the loop is parallel and if its
80  * body is a unique assignment statement or a list containing a
81  * unique assignment.
82  */
85  entity idx = loop_index( obj ) ;
86  range r = loop_range( obj ) ;
87 
88  expression lhs =
90  expression rhs =
94  text t = text_undefined;
95 
96  pips_assert("Loop obj is consistent", loop_consistent_p(obj));
97 
99 
100  new_lhs = expand_expression( lhs, idx, r ) ;
101  new_rhs = expand_expression( rhs, idx, r ) ;
102 
103  pips_assert("new_lhs is consistent", expression_consistent_p(new_lhs));
104  pips_assert("new_rhs is consistent", expression_consistent_p(new_rhs));
105 
106  set_free(vectors);
107 
108  if(!expression_undefined_p(new_lhs) && !expression_undefined_p(new_rhs)) {
109  statement new_s = make_assign_statement( new_lhs, new_rhs );
110 
111  statement_number(new_s) = statement_number(as);
112  /* statement_ordering must be initialized too to avoid a
113  prettyprinter warning */
116  list pdl = NIL;
117  t = text_statement(module, margin, new_s, &pdl);
118  gen_free_list(pdl);
119  /* FI: Although new_s has been converted to text, it cannot
120  always be freed. I do not know which part of new_s is
121  reused in the result of text_statement() or somewhere
122  else... Found with valgrind and validation case
123  Prettyprint/aa01.tpips */
124  //free_statement(new_s);
125  }
126  else {
127  /* No legal vector form has been found */
128  free_expression(new_lhs);
129  free_expression(new_rhs);
130  list pdl = NIL;
131  t = text_loop_default(module, label, margin, obj, n, &pdl, true);
132  gen_free_list(pdl);
133  }
134 
135  pips_assert("Loop obj still is consistent", loop_consistent_p(obj));
136 
137  return t;
138 }
bool expression_consistent_p(expression p)
Definition: ri.c:859
void free_expression(expression p)
Definition: ri.c:853
bool loop_consistent_p(loop p)
Definition: ri.c:1274
statement make_assign_statement(expression, expression)
Definition: statement.c:583
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
void set_free(set)
Definition: set.c:332
@ set_pointer
Definition: newgen_set.h:44
set set_make(set_type)
Create an empty set of any type but hash_private.
Definition: set.c:102
static char * module
Definition: pips.c:74
static statement body_to_assignment_statement(statement b)
The tests necessary to check the underlying assumptions have been performed in text_loop(): b is eith...
Definition: fortran90.c:61
text text_loop_default(entity module, const char *label, int margin, loop obj, int n, list *ppdl, bool is_recursive_p)
exported for fortran90.c
Definition: misc.c:3118
text text_statement(entity, int, statement, list *)
#define loop_body(x)
Definition: ri.h:1644
#define statement_ordering(x)
Definition: ri.h:2454
#define statement_comments(x)
Definition: ri.h:2456
#define instruction_call(x)
Definition: ri.h:1529
#define loop_range(x)
Definition: ri.h:1642
#define statement_number(x)
Definition: ri.h:2452
#define loop_index(x)
Definition: ri.h:1640
#define text_undefined
Definition: text.h:91

References body_to_assignment_statement(), call_arguments, CAR, CDR, expand_expression(), EXPRESSION, expression_consistent_p(), expression_undefined, expression_undefined_p, free_expression(), gen_free_list(), instruction_call, loop_body, loop_consistent_p(), loop_index, loop_range, make_assign_statement(), module, NIL, pips_assert, set_free(), set_make(), set_pointer, statement_comments, statement_instruction, statement_number, statement_ordering, text_loop_default(), text_statement(), text_undefined, and vectors.

Referenced by text_loop().

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

Variable Documentation

◆ vectors

set vectors
static

Prettyprint one FORTRAN 90 loop as an array expression.

Pierre Jouvelot

For one level only loop, with one assignment as body. Replaces occurences of the index variable by ranges in expressions. Ranges are prettyprinted as triplet when they occur as subscript expressions and as vectors with implicit DO otherwise. If the replacement cannot occur, for instance because subscript expressions are coupled, the loop is printed as a loop.

There are/were memory leaks here since a new expression is constructed. FI: To keep track of vectorized subexpressions (a guess...)

Definition at line 56 of file fortran90.c.

Referenced by expand_call(), expand_expression(), expand_reference(), and text_loop_90().