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

Go to the source code of this file.

Functions

entity Generate_C_ReturnLabel (entity m)
 Handling of C return statements. More...
 
statement Generate_C_ReturnStatement ()
 
void Reset_C_ReturnStatement ()
 The return statement must be reset when it is used by the parser to add the return statement to the function body or when a parser error is encountered. More...
 
statement Get_C_ReturnStatement ()
 This function is used to generate all goto's towards the unique return used to C replace return statement and to insert this unique return at the end of the current function's body. More...
 
statement C_MakeReturnStatement (list el, int ln, string c)
 This function creates a goto instruction to label end_label. More...
 
int GetReturnNumber ()
 
void FixCReturnStatements (statement ms)
 When return statements have been encountered, each of them has been replaced by a goto to a unique return statement. More...
 

Variables

static statement C_return_statement = statement_undefined
 Generate a unique call statement to RETURN per module. More...
 
static int number_of_return_statements = -1
 Saved to optimize the internal representation instead of relying on the parser and/or on control_restructure: is it possible to optimize? what is the last expression list returned? Which statement becomes redundant? More...
 
static list last_returned_value = list_undefined
 
static statement last_return_value_assignment = statement_undefined
 
static entity return_value_entity = entity_undefined
 It is saved because it is hard to retrieve from within actual_c_parser() once the aprsing is over. More...
 
static entity return_current_module = entity_undefined
 get_current_module_entity() is reset too early by the parser More...
 

Function Documentation

◆ C_MakeReturnStatement()

statement C_MakeReturnStatement ( list  el,
int  ln,
string  c 
)

This function creates a goto instruction to label end_label.

This is done to eliminate return statements.

Note: I was afraid the mouse trap would not work to analyze multiple procedures but there is no problem. I guess that MakeGotoInst() generates the proper label entity regardless of end_label. FI. Generates the internal representation of a C return statement. If e is an undefined expression, a goto returnlabel is generated. Else, e is assigned to the return value of the current function, a goto is generated and both are returned within a block.

Assign the expression to the return value of the current function

Parameters
ell
lnn

Definition at line 155 of file return.c.

156 {
161 
162  last_returned_value = el;
163 
164  if(!ENDP(el)) {
165  /* Assign the expression to the return value of the current
166  function */
169  if(ENDP(CDR(el))) {
170  expression e = EXPRESSION(CAR(el));
172  }
173  else {
174  pips_internal_error("This case is not implemented yet.");
175  }
176  }
177 
179 
180  if(instruction_undefined_p(ainst)) {
181  inst = ginst;
183  ln,
185  c,
186  inst,
187  NIL,
190  }
191  else {
193  ln,
195  c,
196  ainst,
197  NIL,
201  list sl = CONS(STATEMENT, as, CONS(STATEMENT, gs, NIL));
203  inst = make_instruction_block(sl);
204  s = instruction_to_statement(inst);
205  }
206 
207  pips_assert("inst is consistent", instruction_consistent_p(inst));
208  pips_assert("s is consistent", statement_consistent_p(s));
209 
210 
211  return s;
212 }
bool instruction_consistent_p(instruction p)
Definition: ri.c:1124
bool statement_consistent_p(statement p)
Definition: ri.c:2195
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
synchronization make_synchronization_none(void)
Definition: ri.c:2424
instruction make_instruction_goto(statement _field_)
Definition: ri.c:1181
static statement last_return_value_assignment
Definition: return.c:75
static list last_returned_value
Definition: return.c:74
statement Get_C_ReturnStatement()
This function is used to generate all goto's towards the unique return used to C replace return state...
Definition: return.c:130
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
Definition: statement.c:597
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
instruction make_instruction_block(list statements)
Build an instruction block from a list of statements.
Definition: instruction.c:106
instruction make_assign_instruction(expression l, expression r)
Definition: instruction.c:87
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#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 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 pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_internal_error
Definition: misc-local.h:149
#define STATEMENT_ORDERING_UNDEFINED
mapping.h inclusion
Definition: newgen-local.h:35
#define string_undefined
Definition: newgen_types.h:40
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
entity entity_empty_label(void)
Definition: entity.c:1105
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
extensions empty_extensions(void)
extension.c
Definition: extension.c:43
entity function_to_return_value(entity m)
Returns the entity rv that carries the value returned by module m, when m is not a C void function or...
Definition: module.c:509
#define instruction_undefined_p(x)
Definition: ri.h:1455
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define instruction_undefined
Definition: ri.h:1454
#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, CDR, CONS, empty_extensions(), ENDP, entity_empty_label(), entity_to_expression(), EXPRESSION, f(), function_to_return_value(), Get_C_ReturnStatement(), get_current_module_entity(), instruction_consistent_p(), instruction_to_statement(), instruction_undefined, instruction_undefined_p, last_return_value_assignment, last_returned_value, make_assign_instruction(), make_instruction_block(), make_instruction_goto(), make_statement(), make_synchronization_none(), NIL, pips_assert, pips_internal_error, STATEMENT, statement_consistent_p(), STATEMENT_ORDERING_UNDEFINED, statement_undefined, and string_undefined.

+ Here is the call graph for this function:

◆ FixCReturnStatements()

void FixCReturnStatements ( statement  ms)

When return statements have been encountered, each of them has been replaced by a goto to a unique return statement.

This unique return statement may have to be added to the function body.

How many return statements have been encountered?

nothing to be done

If the return statement is the last statement of the module statement, the goto and the assignment can be replaced by a call to return. Otherwise, a return statement with the proper label must be added at the end of the module statement ms

The goto instruction and, possibly, the return value assignment can be removed: just remove the label?

Do not forget to declare the return variable...

Parameters
mss

Definition at line 223 of file return.c.

224 {
225  if(get_bool_property("C_PARSER_RETURN_SUBSTITUTION")) {
226  /* How many return statements have been encountered? */
227  int nrs = GetReturnNumber();
228  int replace_p = false;
229  if(nrs==-1 || nrs==0)
230  ; /* nothing to be done */
231  else if(nrs==1) {
232  /* If the return statement is the last statement of the module
233  statement, the goto and the assignment can be replaced by a
234  call to return. Otherwise, a return statement with the
235  proper label must be added at the end of the module statement
236  ms */
237  //statement ls = find_last_statement(ms);
238  statement ls = last_statement(ms);
239  if(!statement_undefined_p(ls)) {
241  if(instruction_goto_p(li)) {
242  statement ts = instruction_goto(li);
243  if(ts==C_return_statement) {
244  //instruction lrvai =
245  // statement_instruction(last_return_value_assignment);
246  /* The goto instruction and, possibly, the return value
247  assignment can be removed: just remove the label? */
254  free_instruction(li);
255  //free_instruction(lrvai); contains the expression resued above!
256  replace_p = false;
257  }
258  else
259  replace_p = true;
260  }
261  else
262  replace_p = true;
263  }
264  else
265  replace_p = true;
266  }
267  else if(nrs>1)
268  replace_p = true;
269  else
270  pips_internal_error("The number of return statements has"
271  " not been initialized");
272 
273  if(replace_p) {
274  /* Do not forget to declare the return variable... */
276  pips_assert("ms is a block", statement_block_p(ms));
280  ms);
282  }
284  }
285  }
287 }
call make_call(entity a1, list a2)
Definition: ri.c:269
void free_instruction(instruction p)
Definition: ri.c:1118
static entity return_current_module
get_current_module_entity() is reset too early by the parser
Definition: return.c:82
static entity return_value_entity
It is saved because it is hard to retrieve from within actual_c_parser() once the aprsing is over.
Definition: return.c:80
static statement C_return_statement
Generate a unique call statement to RETURN per module.
Definition: return.c:68
void Reset_C_ReturnStatement()
The return statement must be reset when it is used by the parser to add the return statement to the f...
Definition: return.c:115
int GetReturnNumber()
Definition: return.c:214
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
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
instruction make_continue_instruction()
Creates a CONTINUE instruction, that is the FORTRAN nop, the ";" in C or the "pass" in Python for exa...
Definition: instruction.c:79
void insert_statement(statement, statement, bool)
This is the normal entry point.
Definition: statement.c:2570
statement last_statement(statement)
A simplified version of find_last_statement() located in prettyprint.c and designed to be used within...
Definition: statement.c:168
#define statement_block_p(stat)
#define C_RETURN_FUNCTION_NAME
#define call_to_instruction
entity CreateIntrinsic(string name)
this function does not create an intrinsic function because they must all be created beforehand by th...
Definition: entity.c:1311
void AddLocalEntityToDeclarations(entity, entity, statement)
Add the variable entity e to the list of variables of the function module.
Definition: variable.c:233
#define instruction_goto(x)
Definition: ri.h:1526
#define entity_undefined_p(x)
Definition: ri.h:2762
#define statement_instruction(x)
Definition: ri.h:2458
#define statement_undefined_p(x)
Definition: ri.h:2420
#define instruction_goto_p(x)
Definition: ri.h:1524

References AddLocalEntityToDeclarations(), C_RETURN_FUNCTION_NAME, C_return_statement, call_to_instruction, CreateIntrinsic(), entity_undefined_p, free_instruction(), get_bool_property(), GetReturnNumber(), insert_statement(), instruction_goto, instruction_goto_p, last_return_value_assignment, last_returned_value, last_statement(), make_call(), make_continue_instruction(), pips_assert, pips_internal_error, Reset_C_ReturnStatement(), reset_current_module_entity(), return_current_module, return_value_entity, set_current_module_entity(), statement_block_p, statement_instruction, and statement_undefined_p.

Referenced by actual_c_parser().

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

◆ Generate_C_ReturnLabel()

entity Generate_C_ReturnLabel ( entity  m)

Handling of C return statements.

return.c

Unlike Fortran return statements, C return statements carry the value returned by functions. In some sense, they have a continuation since they return to the caller, but there is no local continuation. So C return cannot be simply replaced by goto statements. This only preserves the control semantics. An additional variable, the return value, must be declared and used to collect information about the different values that are returned. This translation can be removed when there is only one return at the end of the function body. Note that pass restructure_control may be useful for procedure with several returns because unspaghettify, called by the controlizer, is not strong enough.

Francois Irigoin

Definition at line 58 of file return.c.

59 {
61  return l;
62 }
#define LABEL_PREFIX
Definition: naming-local.h:31
#define RETURN_LABEL_NAME
Definition: naming-local.h:106
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
entity make_label(const char *module_name, const char *local_name)
Definition: entity.c:308

References entity_module_name(), LABEL_PREFIX, make_label(), and RETURN_LABEL_NAME.

Referenced by Generate_C_ReturnStatement().

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

◆ Generate_C_ReturnStatement()

statement Generate_C_ReturnStatement ( void  )

Definition at line 84 of file return.c.

85 {
90  type mt = entity_type(m);
93 
94  if(type_void_p(r))
96  else {
102  CONS(EXPRESSION, arg, NIL));
103  }
104 
105  // FI: I'd like to add a return label to this special statement...
107  statement_label(s) = l;
108  return s;
109 }
entity Generate_C_ReturnLabel(entity m)
Handling of C return statements.
Definition: return.c:58
instruction make_call_instruction(entity e, list l)
Build an instruction that call a function entity with an argument list.
Definition: instruction.c:51
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
#define functional_result(x)
Definition: ri.h:1444
#define type_functional(x)
Definition: ri.h:2952
#define statement_label(x)
Definition: ri.h:2450
#define type_void_p(x)
Definition: ri.h:2959
#define entity_type(x)
Definition: ri.h:2792

References C_RETURN_FUNCTION_NAME, CONS, entity_intrinsic(), entity_to_expression(), entity_type, EXPRESSION, f(), function_to_return_value(), functional_result, Generate_C_ReturnLabel(), get_current_module_entity(), instruction_to_statement(), instruction_undefined, make_call_instruction(), NIL, return_current_module, return_value_entity, statement_label, statement_undefined, type_functional, and type_void_p.

Referenced by Get_C_ReturnStatement().

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

◆ Get_C_ReturnStatement()

statement Get_C_ReturnStatement ( void  )

This function is used to generate all goto's towards the unique return used to C replace return statement and to insert this unique return at the end of the current function's body.

Definition at line 130 of file return.c.

131 {
133  pips_assert("No return statement yet\n", number_of_return_statements==-1);
136  }
138  return C_return_statement;
139 }
static int number_of_return_statements
Saved to optimize the internal representation instead of relying on the parser and/or on control_rest...
Definition: return.c:73
statement Generate_C_ReturnStatement()
Definition: return.c:84

References C_return_statement, Generate_C_ReturnStatement(), number_of_return_statements, pips_assert, and statement_undefined_p.

Referenced by C_MakeReturnStatement().

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

◆ GetReturnNumber()

int GetReturnNumber ( void  )

Definition at line 214 of file return.c.

215 {
217 }

References number_of_return_statements.

Referenced by FixCReturnStatements().

+ Here is the caller graph for this function:

◆ Reset_C_ReturnStatement()

void Reset_C_ReturnStatement ( void  )

The return statement must be reset when it is used by the parser to add the return statement to the function body or when a parser error is encountered.

Definition at line 115 of file return.c.

116 {
123  //c_end_label = entity_undefined;
124 }
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
#define entity_undefined
Definition: ri.h:2761

References C_return_statement, entity_undefined, last_return_value_assignment, last_returned_value, list_undefined, number_of_return_statements, return_current_module, return_value_entity, and statement_undefined.

Referenced by c_parser_error(), and FixCReturnStatements().

+ Here is the caller graph for this function:

Variable Documentation

◆ C_return_statement

statement C_return_statement = statement_undefined
static

Generate a unique call statement to RETURN per module.

Saved to be reused each time a return must be converted into a goto b ythe parser

Definition at line 68 of file return.c.

Referenced by FixCReturnStatements(), Get_C_ReturnStatement(), and Reset_C_ReturnStatement().

◆ last_return_value_assignment

statement last_return_value_assignment = statement_undefined
static

Definition at line 75 of file return.c.

Referenced by C_MakeReturnStatement(), FixCReturnStatements(), and Reset_C_ReturnStatement().

◆ last_returned_value

list last_returned_value = list_undefined
static

Definition at line 74 of file return.c.

Referenced by C_MakeReturnStatement(), FixCReturnStatements(), and Reset_C_ReturnStatement().

◆ number_of_return_statements

int number_of_return_statements = -1
static

Saved to optimize the internal representation instead of relying on the parser and/or on control_restructure: is it possible to optimize? what is the last expression list returned? Which statement becomes redundant?

Definition at line 73 of file return.c.

Referenced by Get_C_ReturnStatement(), GetReturnNumber(), and Reset_C_ReturnStatement().

◆ return_current_module

entity return_current_module = entity_undefined
static

get_current_module_entity() is reset too early by the parser

Definition at line 82 of file return.c.

Referenced by FixCReturnStatements(), Generate_C_ReturnStatement(), and Reset_C_ReturnStatement().

◆ return_value_entity

entity return_value_entity = entity_undefined
static

It is saved because it is hard to retrieve from within actual_c_parser() once the aprsing is over.

get_current_module_entity() seems to return an undefined entity

Definition at line 80 of file return.c.

Referenced by FixCReturnStatements(), Generate_C_ReturnStatement(), and Reset_C_ReturnStatement().