PIPS
loop_spaghettify.c File Reference
#include <stdio.h>
#include <ctype.h>
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "effects.h"
#include "resources.h"
#include "misc.h"
#include "ri-util.h"
#include "effects-util.h"
#include "text-util.h"
#include "dg.h"
#include "phrase_tools.h"
#include "spaghettify.h"
+ Include dependency graph for loop_spaghettify.c:

Go to the source code of this file.

Functions

static entity make_index_variable (loop the_loop, statement stat, const char *module_name)
 The spaghettifier is used in context of PHRASE project while creating "Finite State Machine"-like code portions in order to synthetise them in reconfigurables units. More...
 
static entity make_begin_variable (loop the_loop, statement stat, const char *module_name)
 Creates begin variable for a loop the_loop of a statement stat. More...
 
static entity make_end_variable (loop the_loop, statement stat, const char *module_name)
 Creates end variable for a loop the_loop of a statement stat. More...
 
static entity make_increment_variable (loop the_loop, statement stat, const char *module_name)
 Creates increment variable for a loop the_loop of a statement stat. More...
 
static control make_initialization_from_loop (loop the_loop, statement stat, entity index_variable, entity begin_variable, entity end_variable, entity increment_variable)
 Build and return a new control containing initialization statement of the unstructured loop. More...
 
static control make_condition_from_loop (loop the_loop, statement stat, entity index_variable, entity end_variable, entity increment_variable)
 Build and return a new control containing condition statement of the unstructured loop. More...
 
static control make_exit_from_loop ()
 Build and return a new control containing exit statement of the unstructured loop (this is a continue statement) More...
 
static control make_body_from_loop (loop the_loop, const char *module_name, statement stat, entity index_variable, entity increment_variable)
 Build and return a new control containing body statement of the unstructured loop. More...
 
static unstructured make_unstructured_from_loop (loop the_loop, statement stat, const char *module_name)
 Build and return a new unstructured coding the "destructured" loop. More...
 
statement spaghettify_loop (statement stat, const char *module_name)
 This function takes the statement stat as parameter and return a new spaghettized statement, asserting stat is a LOOP statement. More...
 

Function Documentation

◆ make_begin_variable()

static entity make_begin_variable ( loop  the_loop,
statement  stat,
const char *  module_name 
)
static

Creates begin variable for a loop the_loop of a statement stat.

Definition at line 135 of file loop_spaghettify.c.

138 {
141  stat,
142  module_name);
143 }
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
entity make_variable_from_name_and_entity(entity, const char *, statement, const char *)
Build and return new entity obtained by cloning variable cloned_variable, with a name obtained by the...
Definition: phrase_tools.c:325
#define loop_index(x)
Definition: ri.h:1640
#define BEGIN_VARIABLE_NAME
Definition: spaghettify.h:28

References BEGIN_VARIABLE_NAME, loop_index, make_variable_from_name_and_entity(), and module_name().

Referenced by make_unstructured_from_loop().

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

◆ make_body_from_loop()

static control make_body_from_loop ( loop  the_loop,
const char *  module_name,
statement  stat,
entity  index_variable,
entity  increment_variable 
)
static

Build and return a new control containing body statement of the unstructured loop.

Definition at line 307 of file loop_spaghettify.c.

312 {
313  statement assignement_statement
315  entity_to_expression (index_variable),
316  stat);
317  statement spaghettified_body
318  = spaghettify_statement(loop_body(the_loop),
319  module_name);
320  statement increment_statement
322  (index_variable,
324  entity_to_expression (index_variable),
325  entity_to_expression (increment_variable)),
326  stat);
327 
328  sequence body_sequence
329  = make_sequence (CONS(STATEMENT, assignement_statement,
330  CONS(STATEMENT, spaghettified_body,
331  CONS(STATEMENT, increment_statement, NIL))));
332 
333  statement body_statement
335  statement_number(stat),
336  statement_ordering(stat),
339  body_sequence),
340  NIL,NULL,
342  return make_control (body_statement, NIL, NIL);
343 }
statement make_statement(entity a1, intptr_t a2, intptr_t a3, string a4, instruction a5, list a6, string a7, extensions a8, synchronization a9)
Definition: ri.c:2222
instruction make_instruction(enum instruction_utype tag, void *val)
Definition: ri.c:1166
synchronization make_synchronization_none(void)
Definition: ri.c:2424
sequence make_sequence(list a)
Definition: ri.c:2125
control make_control(statement a1, list a2, list a3)
Definition: ri.c:523
#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
statement spaghettify_statement(statement, const char *)
spaghettify.c
Definition: spaghettify.c:85
statement make_assignement_statement(entity, expression, statement)
Build and return new statement which is a assignement of variable a_variable with expression an_expre...
Definition: phrase_tools.c:392
#define PLUS_OPERATOR_NAME
#define empty_comments
Empty comments (i.e.
entity entity_empty_label(void)
Definition: entity.c:1105
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
#define loop_body(x)
Definition: ri.h:1644
#define statement_ordering(x)
Definition: ri.h:2454
@ is_instruction_sequence
Definition: ri.h:1469
#define statement_extensions(x)
Definition: ri.h:2464
#define statement_number(x)
Definition: ri.h:2452
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413

References CONS, empty_comments, entity_empty_label(), entity_intrinsic(), entity_to_expression(), is_instruction_sequence, loop_body, loop_index, make_assignement_statement(), make_control(), make_instruction(), make_sequence(), make_statement(), make_synchronization_none(), MakeBinaryCall(), module_name(), NIL, PLUS_OPERATOR_NAME, spaghettify_statement(), STATEMENT, statement_extensions, statement_number, and statement_ordering.

Referenced by make_unstructured_from_loop().

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

◆ make_condition_from_loop()

static control make_condition_from_loop ( loop  the_loop,
statement  stat,
entity  index_variable,
entity  end_variable,
entity  increment_variable 
)
static

Build and return a new control containing condition statement of the unstructured loop.

Definition at line 228 of file loop_spaghettify.c.

233 {
234  statement condition_statement;
235  test condition_test;
236  intptr_t increment_value;
237  string intrinsic_name;
239 
241  (range_increment(loop_range(the_loop)),
242  &increment_value)) {
243  if (increment_value >= 0) {
244  intrinsic_name = LESS_OR_EQUAL_OPERATOR_NAME;
245  }
246  else {
247  intrinsic_name = GREATER_OR_EQUAL_OPERATOR_NAME;
248  }
250  = MakeBinaryCall (entity_intrinsic(intrinsic_name),
251  entity_to_expression (index_variable),
252  entity_to_expression (end_variable));
253  }
254  else {
255  // Generate (((INDEX'.LE.END').AND.(INC'.GE.0)).OR.((INDEX'.GE.END').AND.(INC'.LE.0)))
260  entity_to_expression (index_variable),
261  entity_to_expression (end_variable)),
263  entity_to_expression (increment_variable),
264  int_to_expression (0))),
267  entity_to_expression (index_variable),
268  entity_to_expression (end_variable)),
270  entity_to_expression (increment_variable),
271  int_to_expression (0))));
272 
273 
274  }
275 
276  condition_test
280 
281 
282  condition_statement = make_statement(entity_empty_label(),
283  statement_number(stat),
284  statement_ordering(stat),
287  condition_test),
288  NIL,NULL,
290 
291  return make_control (condition_statement, NIL, NIL);
292 }
test make_test(expression a1, statement a2, statement a3)
Definition: ri.c:2607
statement make_continue_statement(entity)
Definition: statement.c:953
#define AND_OPERATOR_NAME
FI: intrinsics are defined at a third place after bootstrap and effects! I guess the name should be d...
#define GREATER_OR_EQUAL_OPERATOR_NAME
#define LESS_OR_EQUAL_OPERATOR_NAME
#define OR_OPERATOR_NAME
bool expression_integer_value(expression e, intptr_t *pval)
Definition: eval.c:792
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
#define range_increment(x)
Definition: ri.h:2292
@ is_instruction_test
Definition: ri.h:1470
#define test_condition(x)
Definition: ri.h:2833
#define loop_range(x)
Definition: ri.h:1642
#define intptr_t
Definition: stdint.in.h:294

References AND_OPERATOR_NAME, empty_comments, entity_empty_label(), entity_intrinsic(), entity_to_expression(), expression_integer_value(), GREATER_OR_EQUAL_OPERATOR_NAME, int_to_expression(), intptr_t, is_instruction_test, LESS_OR_EQUAL_OPERATOR_NAME, loop_range, make_continue_statement(), make_control(), make_instruction(), make_statement(), make_synchronization_none(), make_test(), MakeBinaryCall(), NIL, OR_OPERATOR_NAME, range_increment, statement_extensions, statement_number, statement_ordering, and test_condition.

Referenced by make_unstructured_from_loop().

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

◆ make_end_variable()

static entity make_end_variable ( loop  the_loop,
statement  stat,
const char *  module_name 
)
static

Creates end variable for a loop the_loop of a statement stat.

Definition at line 148 of file loop_spaghettify.c.

151 {
154  stat,
155  module_name);
156 }
#define END_VARIABLE_NAME
Definition: spaghettify.h:29

References END_VARIABLE_NAME, loop_index, make_variable_from_name_and_entity(), and module_name().

Referenced by make_unstructured_from_loop().

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

◆ make_exit_from_loop()

static control make_exit_from_loop ( )
static

Build and return a new control containing exit statement of the unstructured loop (this is a continue statement)

Definition at line 298 of file loop_spaghettify.c.

299 {
301 }

References entity_empty_label(), make_continue_statement(), make_control(), and NIL.

Referenced by make_unstructured_from_loop().

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

◆ make_increment_variable()

static entity make_increment_variable ( loop  the_loop,
statement  stat,
const char *  module_name 
)
static

Creates increment variable for a loop the_loop of a statement stat.

Definition at line 161 of file loop_spaghettify.c.

164 {
167  stat,
168  module_name);
169 }
#define INCREMENT_VARIABLE_NAME
Definition: spaghettify.h:30

References INCREMENT_VARIABLE_NAME, loop_index, make_variable_from_name_and_entity(), and module_name().

Referenced by make_unstructured_from_loop().

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

◆ make_index_variable()

static entity make_index_variable ( loop  the_loop,
statement  stat,
const char *  module_name 
)
static

The spaghettifier is used in context of PHRASE project while creating "Finite State Machine"-like code portions in order to synthetise them in reconfigurables units.

This file contains the code used for spaghettify loops.

General syntax of loop in Fortran are:

DO INDEX=BEGIN, END, INCREMENT STATEMENT END DO

where INDEX is an entity (variable) and BEGIN, END, INCREMENT are expressions.

Be careful: Fortran interprets all the values of the loop INDEX, BEGIN, END, INCREMENT before to enter the loop, and those values could therefore be modified inside the loop (during the execution of STATEMENT). That's the reason, to generate equivalent code, why we introduce the variables: INDEX', BEGIN', END', INCREMENT'

If INCREMENT is evaluable and POSITIVE, following code is generated:

BEGIN' = BEGIN END' = END INC' = INC INDEX' = BEGIN' 10 IF (INDEX'.LE.END') THEN INDEX = INDEX' STATEMENT INDEX' = INDEX' + INC' GOTO 10 ENDIF 20 CONTINUE

If INCREMENT is evaluable and NEGATIVE, following code is generated:

BEGIN' = BEGIN END' = END INC' = INC INDEX' = BEGIN' 10 IF (INDEX'.GE.END') THEN INDEX = INDEX' STATEMENT INDEX' = INDEX' + INC' GOTO 10 ENDIF 20 CONTINUE

If INCREMENT is not evaluable, following code is generated:

BEGIN' = BEGIN END' = END INC' = INC INDEX' = BEGIN' 10 IF (((INDEX'.LE.END').AND.(INC'.GE.0)).OR.((INDEX'.GE.END').AND.(INC'.LE.0))) THEN INDEX = INDEX' STATEMENT INDEX' = INDEX' + INC' GOTO 10 ENDIF 20 CONTINUE Creates index variable for a loop the_loop of a statement stat

Definition at line 122 of file loop_spaghettify.c.

125 {
128  stat,
129  module_name);
130 }
#define INDEX_VARIABLE_NAME
Definition: spaghettify.h:27

References INDEX_VARIABLE_NAME, loop_index, make_variable_from_name_and_entity(), and module_name().

Referenced by make_unstructured_from_loop().

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

◆ make_initialization_from_loop()

static control make_initialization_from_loop ( loop  the_loop,
statement  stat,
entity  index_variable,
entity  begin_variable,
entity  end_variable,
entity  increment_variable 
)
static

Build and return a new control containing initialization statement of the unstructured loop.

Definition at line 175 of file loop_spaghettify.c.

181 {
182  statement init_begin_statement;
183  statement init_end_statement;
184  statement init_increment_statement;
185  statement init_index_statement;
186  expression lower = range_lower(loop_range(the_loop));
187  expression upper = range_upper(loop_range(the_loop));
188  expression increment = range_increment(loop_range(the_loop));
189  sequence init_sequence;
190 
191  init_begin_statement
192  = make_assignement_statement (begin_variable, lower, stat);
193  init_end_statement
194  = make_assignement_statement (end_variable, upper, stat);
195  init_increment_statement
196  = make_assignement_statement (increment_variable, increment, stat);
197  init_index_statement
198  = make_assignement_statement (index_variable,
199  entity_to_expression(begin_variable),
200  stat);
201 
202  init_sequence
204  init_begin_statement,
205  CONS(STATEMENT,
206  init_end_statement,
207  CONS(STATEMENT,
208  init_increment_statement,
209  CONS(STATEMENT,
210  init_index_statement,
211  NIL)))));
212 
214  statement_number(stat),
215  statement_ordering(stat),
218  init_sequence),
219  NIL, NULL,
221  NIL, NIL);
222 }
#define range_upper(x)
Definition: ri.h:2290
#define range_lower(x)
Definition: ri.h:2288

References CONS, empty_comments, entity_empty_label(), entity_to_expression(), is_instruction_sequence, loop_range, make_assignement_statement(), make_control(), make_instruction(), make_sequence(), make_statement(), make_synchronization_none(), NIL, range_increment, range_lower, range_upper, STATEMENT, statement_extensions, statement_number, and statement_ordering.

Referenced by make_unstructured_from_loop().

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

◆ make_unstructured_from_loop()

static unstructured make_unstructured_from_loop ( loop  the_loop,
statement  stat,
const char *  module_name 
)
static

Build and return a new unstructured coding the "destructured" loop.

after init, we test

The first connexion is the false one

false condition, we exit from loop

true condition, we go to body

after body, we go back to condition

Definition at line 349 of file loop_spaghettify.c.

352 {
353  entity index_variable = make_index_variable (the_loop, stat, module_name);
354  entity begin_variable = make_begin_variable (the_loop, stat, module_name);
355  entity end_variable = make_end_variable (the_loop, stat, module_name);
356  entity increment_variable = make_increment_variable (the_loop, stat, module_name);
358  = make_initialization_from_loop (the_loop,
359  stat,
360  index_variable,
361  begin_variable,
362  end_variable,
363  increment_variable);
364  control condition = make_condition_from_loop (the_loop,
365  stat,
366  index_variable,
367  end_variable,
368  increment_variable);
370  control body = make_body_from_loop (the_loop,
371  module_name,
372  stat,
373  index_variable,
374  increment_variable);
375 
376  link_2_control_nodes (initialization, condition); /* after init, we test */
377 
378  /* The first connexion is the false one */
379  link_2_control_nodes (condition, exit); /* false condition, we exit from loop */
380  link_2_control_nodes (condition, body); /* true condition, we go to body */
381 
382  link_2_control_nodes (body, condition); /* after body, we go back to condition */
383 
385 }
unstructured make_unstructured(control a1, control a2)
Definition: ri.c:2778
void initialization(graph dg, gen_array_t annotations)
Definition: cost_model.c:267
void link_2_control_nodes(control source, control target)
Add an edge between 2 control nodes.
Definition: control.c:1193
static control make_condition_from_loop(loop the_loop, statement stat, entity index_variable, entity end_variable, entity increment_variable)
Build and return a new control containing condition statement of the unstructured loop.
static control make_body_from_loop(loop the_loop, const char *module_name, statement stat, entity index_variable, entity increment_variable)
Build and return a new control containing body statement of the unstructured loop.
static entity make_index_variable(loop the_loop, statement stat, const char *module_name)
The spaghettifier is used in context of PHRASE project while creating "Finite State Machine"-like cod...
static control make_initialization_from_loop(loop the_loop, statement stat, entity index_variable, entity begin_variable, entity end_variable, entity increment_variable)
Build and return a new control containing initialization statement of the unstructured loop.
static entity make_increment_variable(loop the_loop, statement stat, const char *module_name)
Creates increment variable for a loop the_loop of a statement stat.
static control make_exit_from_loop()
Build and return a new control containing exit statement of the unstructured loop (this is a continue...
static entity make_end_variable(loop the_loop, statement stat, const char *module_name)
Creates end variable for a loop the_loop of a statement stat.
static entity make_begin_variable(loop the_loop, statement stat, const char *module_name)
Creates begin variable for a loop the_loop of a statement stat.
#define exit(code)
Definition: misc-local.h:54

References exit, initialization(), link_2_control_nodes(), make_begin_variable(), make_body_from_loop(), make_condition_from_loop(), make_end_variable(), make_exit_from_loop(), make_increment_variable(), make_index_variable(), make_initialization_from_loop(), make_unstructured(), and module_name().

Referenced by spaghettify_loop().

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

◆ spaghettify_loop()

statement spaghettify_loop ( statement  stat,
const char *  module_name 
)

This function takes the statement stat as parameter and return a new spaghettized statement, asserting stat is a LOOP statement.

loop_spaghettify.c

Parameters
stattat
module_nameodule_name

Definition at line 391 of file loop_spaghettify.c.

392 {
393  statement returned_statement = stat;
394  instruction unstructured_instruction;
395  unstructured new_unstructured;
396 
397  pips_assert("Statement is LOOP in FSM_GENERATION",
400 
401  pips_debug(2, "spaghettify_loop, module %s\n", module_name);
402  new_unstructured = make_unstructured_from_loop (statement_loop(stat),
403  stat,
404  module_name);
405 
406  unstructured_instruction = make_instruction(is_instruction_unstructured,
407  new_unstructured);
408 
409  statement_instruction(returned_statement) = unstructured_instruction;
410 
411  return returned_statement;
412 }
loop statement_loop(statement)
Get the loop of a statement.
Definition: statement.c:1374
static unstructured make_unstructured_from_loop(loop the_loop, statement stat, const char *module_name)
Build and return a new unstructured coding the "destructured" loop.
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
@ is_instruction_unstructured
Definition: ri.h:1475
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define statement_instruction(x)
Definition: ri.h:2458

References instruction_tag, is_instruction_loop, is_instruction_unstructured, make_instruction(), make_unstructured_from_loop(), module_name(), pips_assert, pips_debug, statement_instruction, and statement_loop().

Referenced by full_spaghettify_statement(), and spaghettify_statement().

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