PIPS
procedure.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "genC.h"
#include "linear.h"
#include "misc.h"
#include "properties.h"
#include "pipsdbm.h"
#include "ri-util.h"
#include "workspace-util.h"
#include "control.h"
#include "prettyprint.h"
#include "phases.h"
#include "pipsmake.h"
#include "syntax.h"
#include "parser_private.h"
#include "syn_yacc.h"
+ Include dependency graph for procedure.c:

Go to the source code of this file.

Functions

void init_ghost_variable_entities ()
 procedure.c More...
 
void substitute_ghost_variable_in_expression (expression expr, entity v, entity f)
 
void substitute_ghost_variable_in_statement (statement stmt, entity v, entity f)
 
void remove_ghost_variable_entities (bool substitute_p)
 
void add_ghost_variable_entity (entity e)
 
void reify_ghost_variable_entity (entity e)
 It is possible to change one's mind and effectively use an entity which was previously assumed useless. More...
 
bool ghost_variable_entity_p (entity e)
 
void BeginingOfProcedure ()
 this function is called each time a new procedure is encountered. More...
 
void update_called_modules (entity e)
 
void remove_from_called_modules (entity e)
 macros are added, although they should not have been. More...
 
void AbortOfProcedure ()
 
static bool gather_implicit_indices (call c)
 
static bool fix_storage (reference r)
 
static int implied_do_reference_number (expression)
 forward declaration More...
 
static int expression_reference_number (expression e)
 
static list find_target_position (list cvl, int ctp, int *pmin_cp, int *pmax_cp, expression *pcve)
 
static void store_initial_value (entity var, expression val)
 Integer and bool initial values are stored as int, float, string and maybe complex initial values are stored as entities. More...
 
static void process_value_list (list vl, list isvs, list svps)
 
static void process_static_initialization (call c)
 
static void process_static_initializations ()
 
void EndOfProcedure ()
 This function is called when the parsing of a procedure is completed. More...
 
void UpdateFunctionalType (entity f, list l)
 This function analyzes the CurrentFunction formal parameter list to determine the CurrentFunction functional type. More...
 
void remove_module_entity (entity m)
 
void MakeCurrentFunction (type t, int msf, const char *cfn, list lfp)
 this function creates one entity cf that represents the Fortran function f being analyzed. More...
 
void ResetEntries ()
 
void AbortEntries ()
 
bool EmptyEntryListsP ()
 
void AddEntryLabel (entity l)
 
void AddEntryTarget (statement s)
 
void AddEntryEntity (entity e)
 
void AddEffectiveFormalParameter (entity f)
 Keep track of the formal parameters for the current module. More...
 
bool IsEffectiveFormalParameterP (entity f)
 
static list TranslateEntryFormals (entity e, list lfp)
 list of formal parameters wrongly declared in current module More...
 
static void MakeEntryCommon (entity m, entity a)
 Static variables in a module with entries must be redeclared as stored in a common in order to be accessible from all modules derived from the entries. More...
 
entity SafeLocalToGlobal (entity e, type r)
 A local entity might have been created but found out later to be global, depending on the order of declaration statements (see MakeExternalFunction()). More...
 
type MakeResultType (entity e, type r)
 The result type of a function may be carried by e, by r or be implicit. More...
 
entity LocalToGlobal (entity e)
 
instruction MakeEntry (entity e, list lfp)
 An ENTRY statement is substituted by a labelled continue. More...
 
static statement BuildStatementForEntry (entity cm, entity e, statement t)
 Build an entry version of the current module statement. More...
 
static void ProcessEntry (entity cm, entity e, statement t)
 
void ProcessEntries ()
 
entity NameToFunctionalEntity (string name)
 
void TypeFunctionalEntity (entity fe, type r)
 
entity MakeExternalFunction (entity e, type r)
 
entity DeclareExternalFunction (entity e)
 
void MakeFormalParameter (entity m, entity fp, int nfp)
 This function transforms an untyped entity into a formal parameter. More...
 
void ScanFormalParameters (entity m, list l)
 this function scans the formal parameter list. More...
 
void UpdateFormalStorages (entity m, list lfp)
 this function check and set if necessary the storage of formal parameters in lfp. More...
 

Variables

static list called_modules = list_undefined
 list of called subroutines or functions More...
 
static statement function_body = statement_undefined
 statement of current function More...
 
static list ghost_variable_entities = list_undefined
 list of potential local or top-level variables that turned out to be useless. More...
 
static list implicit_do_index_set = list_undefined
 
static list entry_labels = NIL
 Processing of entries: when an ENTRY statement is encountered, it is replaced by a labelled CONTINUE and the entry is declared as function or a subroutine, depending on its type. More...
 
static list entry_targets = NIL
 
static list entry_entities = NIL
 
static list effective_formal_parameters = NIL
 

Function Documentation

◆ AbortEntries()

void AbortEntries ( void  )

Useless entities should be reset

the current module statement is used when processing entries

Definition at line 1473 of file procedure.c.

1474 {
1475  /* Useless entities should be reset */
1476 
1477  MAP(ENTITY, el, {
1478  free_entity(el);
1479  }, entry_labels);
1481  entry_labels = NIL;
1482 
1483  MAP(ENTITY, et, {
1484  free_entity(et);
1485  }, entry_targets);
1487  entry_targets = NIL;
1488 
1489  MAP(ENTITY, ee, {
1490  CleanLocalEntities(ee);
1491  free_entity(ee);
1492  }, entry_entities);
1494  entry_entities = NIL;
1495 
1496  MAP(ENTITY, efp, {
1497  free_entity(efp);
1498  }, entry_targets);
1501 
1502  /* the current module statement is used when processing entries */
1504 }
void free_entity(entity p)
Definition: ri.c:2524
void CleanLocalEntities(entity function)
Fortran version.
Definition: clean.c:140
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#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
static list entry_entities
Definition: procedure.c:1455
static list effective_formal_parameters
Definition: procedure.c:1456
static list entry_labels
Processing of entries: when an ENTRY statement is encountered, it is replaced by a labelled CONTINUE ...
Definition: procedure.c:1453
static list entry_targets
Definition: procedure.c:1454
void error_reset_current_module_statement(void)
To be called by an error management routine only.
Definition: static.c:234
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755

References CleanLocalEntities(), effective_formal_parameters, ENTITY, entry_entities, entry_labels, entry_targets, error_reset_current_module_statement(), free_entity(), gen_free_list(), MAP, and NIL.

Referenced by ParserError().

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

◆ AbortOfProcedure()

void AbortOfProcedure ( void  )

get rid of ghost variable entities

Definition at line 386 of file procedure.c.

387 {
388  /* get rid of ghost variable entities */
391 
392  (void) ResetBlockStack() ;
393 }
#define list_undefined_p(c)
Return if a list is undefined.
Definition: newgen_list.h:75
static list ghost_variable_entities
list of potential local or top-level variables that turned out to be useless.
Definition: procedure.c:67
void remove_ghost_variable_entities(bool substitute_p)
Definition: procedure.c:206
void ResetBlockStack()
Definition: statement.c:203

References ghost_variable_entities, list_undefined_p, remove_ghost_variable_entities(), and ResetBlockStack().

Referenced by ParserError().

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

◆ add_ghost_variable_entity()

void add_ghost_variable_entity ( entity  e)

Definition at line 275 of file procedure.c.

276 {
279 }
cons * arguments_add_entity(cons *a, entity e)
Definition: arguments.c:85
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172

References arguments_add_entity(), ghost_variable_entities, list_undefined_p, and pips_assert.

Referenced by SafeLocalToGlobal().

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

◆ AddEffectiveFormalParameter()

void AddEffectiveFormalParameter ( entity  f)

Keep track of the formal parameters for the current module.

Definition at line 1529 of file procedure.c.

1530 {
1532 }
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15

References arguments_add_entity(), effective_formal_parameters, and f().

Referenced by MakeEntry().

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

◆ AddEntryEntity()

void AddEntryEntity ( entity  e)

Definition at line 1523 of file procedure.c.

1524 {
1526 }

References arguments_add_entity(), and entry_entities.

Referenced by MakeEntry().

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

◆ AddEntryLabel()

void AddEntryLabel ( entity  l)

Definition at line 1513 of file procedure.c.

1514 {
1516 }

References arguments_add_entity(), and entry_labels.

Referenced by MakeEntry().

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

◆ AddEntryTarget()

void AddEntryTarget ( statement  s)

Definition at line 1518 of file procedure.c.

1519 {
1521 }
#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 STATEMENT(x)
STATEMENT.
Definition: ri.h:2413

References CONS, entry_targets, gen_nconc(), NIL, and STATEMENT.

Referenced by MakeEntry().

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

◆ BeginingOfProcedure()

void BeginingOfProcedure ( void  )

this function is called each time a new procedure is encountered.

reset_current_module_entity();

Definition at line 301 of file procedure.c.

302 {
303  /* reset_current_module_entity(); */
304  InitImplicit();
306 }
void InitImplicit()
this function initializes the data structure used to compute implicit types
Definition: declaration.c:1271
static list called_modules
list of called subroutines or functions
Definition: procedure.c:57

References called_modules, InitImplicit(), and NIL.

+ Here is the call graph for this function:

◆ BuildStatementForEntry()

static statement BuildStatementForEntry ( entity  cm,
entity  e,
statement  t 
)
static

Build an entry version of the current module statement.

The copy_statement() is not consistent with the use of statement t. You have to free s in a very careful way

current module statement

statement for entry e

temporary statement list

Let's get rid of s without destroying cms: do not forget the goto t!

Definition at line 1989 of file procedure.c.

1993 {
1996  /* The copy_statement() is not consistent with the use of statement t.
1997  * You have to free s in a very careful way
1998  */
1999  statement cms = get_current_module_statement(); /* current module statement */
2000  statement es = statement_undefined; /* statement for entry e */
2001  list l = NIL; /* temporary statement list */
2002 
2003  pips_debug(1, "Begin for entry %s in module %s\n",
2004  entity_name(e), entity_name(cm));
2005 
2006  pips_assert("jump consistent", statement_consistent_p(jump));
2007  pips_assert("cms consistent", statement_consistent_p(cms));
2008 
2010  CONS(STATEMENT, jump,
2011  CONS(STATEMENT, cms,
2012  NIL)));
2013  es = copy_statement(s);
2014 
2015  pips_assert("s consistent", statement_consistent_p(s));
2016  pips_assert("es consistent", statement_consistent_p(es));
2017 
2018  /* Let's get rid of s without destroying cms: do not forget the goto t! */
2020  pips_assert("cms is the second statement of the block",
2021  STATEMENT(CAR(CDR(l))) == cms);
2025  free_statement(s);
2026 
2027  pips_assert("es is still consistent", statement_consistent_p(es));
2028  pips_assert("cms is still consistent", statement_consistent_p(cms));
2029 
2030  pips_debug(1, "End for entry %s in module %s\n",
2031  entity_name(e), entity_name(cm));
2032 
2033  return es;
2034 }
statement copy_statement(statement p)
STATEMENT.
Definition: ri.c:2186
bool statement_consistent_p(statement p)
Definition: ri.c:2195
instruction make_instruction(enum instruction_utype tag, void *val)
Definition: ri.c:1166
void free_statement(statement p)
Definition: ri.c:2189
statement make_block_statement(list)
Make a block statement from a list of statement.
Definition: statement.c:616
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
Definition: statement.c:597
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
#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_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define instruction_block(i)
#define STATEMENT_(x)
Definition: ri.h:2416
#define instruction_goto(x)
Definition: ri.h:1526
@ is_instruction_goto
Definition: ri.h:1473
#define entity_name(x)
Definition: ri.h:2790
#define statement_instruction(x)
Definition: ri.h:2458
#define statement_undefined
Definition: ri.h:2419
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References CAR, CDR, CONS, copy_statement(), entity_name, free_statement(), get_current_module_statement(), instruction_block, instruction_goto, instruction_to_statement(), is_instruction_goto, make_block_statement(), make_instruction(), NIL, pips_assert, pips_debug, STATEMENT, STATEMENT_, statement_consistent_p(), statement_instruction, and statement_undefined.

Referenced by ProcessEntry().

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

◆ DeclareExternalFunction()

entity DeclareExternalFunction ( entity  e)

It might be better to declare an unknown type as result type but I decided to fix the problem later. When a call is later encountered, the result type is set to void.

Parameters
eentity to be turned into external function or subroutine, except if it is a formal functional parameter.

Definition at line 2426 of file procedure.c.

2429 {
2430  entity fe = entity_undefined;
2431 
2436  fe = e;
2437  }
2438  else {
2439  /* It might be better to declare an unknown type as result type but I
2440  decided to fix the problem later. When a call is later encountered,
2441  the result type is set to void. */
2443 
2446  "Name conflict between user declared module %s and intrinsic %s\n",
2448  ParserError("DeclareExternalFunction",
2449  "Name conflict with intrinsic because PIPS does not support"
2450  " a specific name space for intrinsics. "
2451  "Please change your function or subroutine name.");
2452  }
2453  }
2454 
2455  return fe;
2456 }
bool storage_defined_p(storage p)
Definition: ri.c:2241
#define pips_user_warning
Definition: misc-local.h:146
entity MakeExternalFunction(entity e, type r)
Definition: procedure.c:2372
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
#define type_functional_p(x)
Definition: ri.h:2950
#define storage_formal_p(x)
Definition: ri.h:2522
#define value_intrinsic_p(x)
Definition: ri.h:3074
#define entity_storage(x)
Definition: ri.h:2794
#define type_undefined_p(x)
Definition: ri.h:2884
#define entity_undefined
Definition: ri.h:2761
#define type_undefined
Definition: ri.h:2883
#define entity_type(x)
Definition: ri.h:2792
#define entity_initial(x)
Definition: ri.h:2796
bool ParserError(const char *f, const char *m)
Definition: parser.c:116

References entity_initial, entity_storage, entity_type, entity_undefined, MakeExternalFunction(), module_local_name(), ParserError(), pips_user_warning, storage_defined_p(), storage_formal_p, type_functional_p, type_undefined, type_undefined_p, and value_intrinsic_p.

+ Here is the call graph for this function:

◆ EmptyEntryListsP()

bool EmptyEntryListsP ( void  )

Definition at line 1506 of file procedure.c.

1507 {
1508  bool empty = ((entry_labels==NIL) && (entry_entities==NIL));
1509 
1510  return empty;
1511 }
@ empty
b1 < bj -> h1/hj = empty
Definition: union-local.h:64

References empty, entry_entities, entry_labels, and NIL.

Referenced by EndOfProcedure(), MakeEntry(), and the_actual_parser().

+ Here is the caller graph for this function:

◆ EndOfProcedure()

void EndOfProcedure ( void  )

This function is called when the parsing of a procedure is completed.

It performs a few calculations which cannot be done on the fly such as address computations for static and dynamic areas and commons.

And it writes the internal representation of the CurrentFunction with a call to gen_free (?).

get rid of ghost variable entities and substitute them if necessary

we generate the last statement to carry a label or a comment

|| iPrevComm != 0

we generate statement last+1 to eliminate returns

Check the block stack

are there undefined gotos ?

The following calls could be located in check_first_statement() which is called when the first executable statement is encountered. At that point, many declaration related problems should be fixed or fixeable. But additional undeclared variables will be added to the dynamic area and their addresses must be computed. At least, ComputeAddresses() must stay here.. so I keep all these calls together.

Must be performed before equivalence resolution, for user declared commons whose declarations are stronger than equivalences

Use equivalence chains to update storages of equivalenced and of variables implicitly declared in DynamicArea, or implicitly thru DATA or explicitly thru SAVE declared in StaticArea

Initialize the shared field in ram storage

Now that retyping and equivalences have been taken into account:

Why keep it in (apparent) declaration order rather than alphabetical order? Because some later processing may be based on this assumption. Sort can be performed before printouts.

remove hpfc special routines if required.

done here. affects callees and code. FC.

the current package is re-initialized

Definition at line 979 of file procedure.c.

980 {
981  entity CurrentFunction = get_current_module_entity();
982 
983  pips_debug(8, "Begin for module %s\n",
984  entity_name(CurrentFunction));
985 
986  pips_debug(8, "checking code consistency = %d\n",
988 
989  ifdebug(8) {
990  pips_debug(8, "Declarations inherited from module %s:\n",
991  module_local_name(CurrentFunction));
992  dump_arguments(entity_declarations(CurrentFunction));
993  }
994 
995  /* get rid of ghost variable entities and substitute them if necessary */
997 
998  /* we generate the last statement to carry a label or a comment */
999  if (strlen(lab_I) != 0 /* || iPrevComm != 0 */ ) {
1001  }
1002 
1003  /* we generate statement last+1 to eliminate returns */
1004  GenerateReturn();
1005 
1006  uses_alternate_return(false);
1009 
1010  /* Check the block stack */
1011  (void) PopBlock() ;
1012  if (!IsBlockStackEmpty())
1013  ParserError("EndOfProcedure",
1014  "bad program structure: missing ENDDO and/or ENDIF\n");
1015 
1016  /* are there undefined gotos ? */
1018 
1019  /* The following calls could be located in check_first_statement()
1020  * which is called when the first executable statement is
1021  * encountered. At that point, many declaration related
1022  * problems should be fixed or fixeable. But additional
1023  * undeclared variables will be added to the dynamic area
1024  * and their addresses must be computed. At least, ComputeAddresses()
1025  * must stay here.. so I keep all these calls together.
1026  */
1027  UpdateFunctionalType(CurrentFunction,
1029 
1031 
1032  /* Must be performed before equivalence resolution, for user declared
1033  commons whose declarations are stronger than equivalences */
1034  update_user_common_layouts(CurrentFunction);
1035 
1037  /* Use equivalence chains to update storages of equivalenced and of
1038  variables implicitly declared in DynamicArea, or implicitly thru
1039  DATA or explicitly thru SAVE declared in StaticArea */
1040  ComputeAddresses();
1041 
1042  /* Initialize the shared field in ram storage */
1043  SaveChains();
1044 
1045  /* Now that retyping and equivalences have been taken into account: */
1047 
1048  /* Why keep it in (apparent) declaration order rather than
1049  alphabetical order? Because some later processing may be based on
1050  this assumption. Sort can be performed before printouts. */
1051  code_declarations(EntityCode(CurrentFunction)) =
1052  gen_nreverse(code_declarations(EntityCode(CurrentFunction))) ;
1053 
1054  if (get_bool_property("PARSER_DUMP_SYMBOL_TABLE"))
1055  fprint_environment(stderr, CurrentFunction);
1056 
1057  ifdebug(5){
1058  fprintf(stderr, "Parser: checking callees consistency = %d\n",
1060  }
1061 
1062  /* remove hpfc special routines if required.
1063  */
1064  if (get_bool_property("HPFC_FILTER_CALLEES"))
1065  {
1066  list l = NIL;
1067  string s;
1068 
1069  MAPL(cs,
1070  {
1071  s = STRING(CAR(cs));
1072 
1074  {
1075  pips_debug(3, "ignoring %s\n", s);
1076  }
1077  else
1078  l = CONS(STRING, s, l);
1079  },
1080  called_modules);
1081 
1083  called_modules = l;
1084  }
1085 
1086  /* done here. affects callees and code. FC.
1087  */
1090 
1091  if(!EmptyEntryListsP()) {
1093  ProcessEntries();
1095  }
1096 
1098 
1099  DB_PUT_MEMORY_RESOURCE(DBR_CALLEES,
1100  module_local_name(CurrentFunction),
1101  (char*) make_callees(called_modules));
1102 
1103  pips_debug(5, "checking code consistency = %d\n",
1105 
1106  DB_PUT_MEMORY_RESOURCE(DBR_PARSED_CODE,
1107  module_local_name(CurrentFunction),
1108  (char *)function_body);
1109 
1110  /* the current package is re-initialized */
1112  ResetChains();
1116 
1117  pips_debug(5, "checking code consistency after resettings = %d\n",
1119 
1120  pips_debug(8, "End for module %s\n", entity_name(CurrentFunction));
1121 }
callees make_callees(list a)
Definition: ri.c:227
bool callees_consistent_p(callees p)
Definition: ri.c:200
void dump_arguments(cons *args)
entity_name is a macro, hence the code replication
Definition: arguments.c:69
entity DynamicArea
These global variables are declared in ri-util/util.c.
Definition: area.c:57
entity StaticArea
Definition: area.c:58
void update_user_common_layouts(entity m)
Check...
Definition: declaration.c:1670
void update_common_sizes(void)
Definition: declaration.c:1215
void reset_common_size_map()
Definition: declaration.c:954
void SaveChains()
Initialize the shared fields of aliased variables.
Definition: equivalence.c:859
void ResetChains()
undefine chains between two successives calls to parser
Definition: equivalence.c:65
void ComputeEquivalences()
This function merges all the equivalence chains to take into account equivalences due to transitivity...
Definition: equivalence.c:215
void ComputeAddresses()
This function computes an address for every variable.
Definition: equivalence.c:503
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define STRING(x)
Definition: genC.h:87
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 get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
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
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
#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 DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
Definition: pipsdbm-local.h:66
void parser_substitute_all_macros(statement s)
Definition: macros.c:294
void parser_close_macros_support(void)
Definition: macros.c:72
#define TOP_LEVEL_MODULE_NAME
Module containing the global variables in Fortran and C.
Definition: naming-local.h:101
void ProcessEntries()
Definition: procedure.c:2171
static statement function_body
statement of current function
Definition: procedure.c:60
static void process_static_initializations()
Definition: procedure.c:945
bool EmptyEntryListsP()
Definition: procedure.c:1506
void UpdateFunctionalType(entity f, list l)
This function analyzes the CurrentFunction formal parameter list to determine the CurrentFunction fun...
Definition: procedure.c:1131
#define entity_declarations(e)
MISC: newgen shorthands.
void fprint_environment(FILE *fd, entity m)
Definition: declarations.c:287
code EntityCode(entity e)
this function checks that e has an initial value code.
Definition: entity.c:301
bool hpf_directive_string_p(const char *s)
recognize an hpf directive special entity.
Definition: hpfc.c:51
bool keep_directive_in_code_p(const char *s)
whether an entity must be kept in the code.
Definition: hpfc.c:101
#define code_declarations(x)
Definition: ri.h:784
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
#define ifdebug(n)
Definition: sg.c:47
cons * FormalParameters
the current function
Definition: parser.c:55
char lab_I[6]
Definition: parser.c:69
const char * CurrentPackage
the name of the current package, i.e.
Definition: parser.c:58
void SubstituteAlternateReturns(const char *option)
return.c
Definition: return.c:59
void uses_alternate_return(bool use)
Definition: return.c:171
void ResetReturnCodeVariable()
Definition: return.c:151
void GenerateReturn()
Generate a unique call to RETURN per module.
Definition: return.c:499
bool IsBlockStackEmpty()
Definition: statement.c:209
void CheckAndInitializeStmt(void)
this function looks for undefined labels.
Definition: statement.c:113
void LinkInstToCurrentBlock(instruction i, bool number_it)
this function links the instruction i to the current block of statements.
Definition: statement.c:529
instruction PopBlock()
Definition: statement.c:238

References called_modules, callees_consistent_p(), CAR, CheckAndInitializeStmt(), code_declarations, ComputeAddresses(), ComputeEquivalences(), CONS, CurrentPackage, DB_PUT_MEMORY_RESOURCE, dump_arguments(), DynamicArea, EmptyEntryListsP(), entity_declarations, entity_name, entity_undefined, EntityCode(), FormalParameters, fprint_environment(), fprintf(), function_body, gen_free_list(), gen_nreverse(), GenerateReturn(), get_bool_property(), get_current_module_entity(), hpf_directive_string_p(), ifdebug, IsBlockStackEmpty(), keep_directive_in_code_p(), lab_I, LinkInstToCurrentBlock(), make_callees(), make_continue_instruction(), MAPL, module_local_name(), NIL, parser_close_macros_support(), parser_substitute_all_macros(), ParserError(), pips_debug, PopBlock(), process_static_initializations(), ProcessEntries(), remove_ghost_variable_entities(), reset_common_size_map(), reset_current_module_entity(), reset_current_module_statement(), ResetChains(), ResetReturnCodeVariable(), SaveChains(), set_current_module_statement(), statement_consistent_p(), StaticArea, STRING, SubstituteAlternateReturns(), TOP_LEVEL_MODULE_NAME, update_common_sizes(), update_user_common_layouts(), UpdateFunctionalType(), and uses_alternate_return().

+ Here is the call graph for this function:

◆ expression_reference_number()

static int expression_reference_number ( expression  e)
static

Number of Value Positions

A scalar is referenced

An array element is referenced

A whole array is initialized

substring is equivalent to one reference

substring is equivalent to one reference

Definition at line 494 of file procedure.c.

495 {
496  int nvp = 0; /* Number of Value Positions */
497 
498  pips_debug(2, "Begin\n");
499 
500  if(expression_reference_p(e)) {
502 
503  if(entity_scalar_p(v)) {
504  /* A scalar is referenced */
505  pips_user_warning("Scalar variable %s initialized by an DATA implied do",
506  entity_local_name(v));
507  ParserError("expression_reference_number",
508  "Scalar variable initialized by an DATA implied do");
509  }
511  /* An array element is referenced */
512  nvp++;
513  }
514  else {
515  /* A whole array is initialized */
516  int ne = -1;
518 
520  pips_user_warning("Varying size of array \"%s\"\n", entity_name(v));
521  ParserError("expression_reference_number",
522  "Fortran standard prohibit varying size array in DATA statements.\n");
523  }
524  nvp += ne;
525  }
526  }
527  else if(expression_call_p(e)) {
529 
530  if(strcmp(entity_local_name(f), IMPLIED_DO_NAME)==0) {
531  int lvp = implied_do_reference_number(e);
532 
533  if(lvp<=0) {
534  pips_user_warning("Cannot deal with non-constant loop bounds\n");
535  }
536 
537  nvp += lvp;
538  }
539  else if(strcmp(entity_local_name(f), SUBSTRING_FUNCTION_NAME)==0) {
540  /* substring is equivalent to one reference */
541  nvp++;
542  }
543  else if(strcmp(entity_local_name(f), IO_LIST_STRING_NAME)==0) {
544  /* substring is equivalent to one reference */
545  nvp=0;
546  }
547  else {
548  pips_user_warning("Unexpected call to function %s\n", entity_module_name(f));
549  ParserError("expression_reference_number", "Unexpected function call");
550  }
551  }
552  else {
553  ParserError("expression_reference_number", "Unexpected range");
554  }
555 
556  pips_debug(2, "End with nvp = %d\n", nvp);
557 
558  return nvp;
559 }
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
static int implied_do_reference_number(expression)
forward declaration
Definition: procedure.c:561
#define SUBSTRING_FUNCTION_NAME
#define IMPLIED_DO_NAME
Definition: ri-util-local.h:75
#define IO_LIST_STRING_NAME
Definition: ri-util-local.h:82
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
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
bool expression_call_p(expression e)
Definition: expression.c:415
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
bool NumberOfElements(basic, list, int *)
Definition: size.c:403
bool entity_scalar_p(entity)
The concrete type of e is a scalar type.
Definition: variable.c:1113
#define call_function(x)
Definition: ri.h:709
#define reference_variable(x)
Definition: ri.h:2326
#define type_variable(x)
Definition: ri.h:2949
#define reference_indices(x)
Definition: ri.h:2328
#define syntax_call(x)
Definition: ri.h:2736
#define variable_dimensions(x)
Definition: ri.h:3122
#define expression_syntax(x)
Definition: ri.h:1247
#define variable_basic(x)
Definition: ri.h:3120

References call_function, ENDP, entity_local_name(), entity_module_name(), entity_name, entity_scalar_p(), entity_type, expression_call_p(), expression_reference(), expression_reference_p(), expression_syntax, f(), IMPLIED_DO_NAME, implied_do_reference_number(), IO_LIST_STRING_NAME, NumberOfElements(), ParserError(), pips_debug, pips_user_warning, reference_indices, reference_variable, SUBSTRING_FUNCTION_NAME, syntax_call, type_variable, variable_basic, and variable_dimensions.

Referenced by implied_do_reference_number(), and process_static_initialization().

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

◆ find_target_position()

static list find_target_position ( list  cvl,
int  ctp,
int pmin_cp,
int pmax_cp,
expression pcve 
)
static

Local Current Value expression List

Value Set

Value Set

Find the repeat factor

Repeat Factor Expression

Constant Value Expression

Default repeat factor

pips_assert("The repeat function is called", ENTITY_REPEAT_VALUE_P(rf));

Definition at line 613 of file procedure.c.

614 {
615  list lcvl = cvl; /* Local Current Value expression List*/
616 
617  pips_debug(2, "Begin for target ctp=%d with window [%d, %d]\n", ctp, *pmin_cp, *pmax_cp);
618  pips_debug(2, "and with %zd value sets\n", gen_length(cvl));
619 
620  while(ctp > *pmax_cp) {
621  expression vs = expression_undefined; /* Value Set */
622 
623  pips_debug(2, "Iterate for target ctp=%d with window [%d, %d]\n", ctp, *pmin_cp, *pmax_cp);
624 
625  if(ENDP(lcvl)) {
626  pips_user_warning("Looking for %dth value, could find only %d\n",
627  ctp, *pmax_cp);
628  ParserError("find_target_position", "Not enough values in DATA statement");
629  }
630 
631  vs = EXPRESSION(CAR(lcvl)); /* Value Set */
632 
633  POP(lcvl);
634  *pmin_cp = *pmax_cp+1;
635 
636  if(expression_call_p(vs)) {
637  /* Find the repeat factor */
639  entity rf = call_function(c);
640  list args = call_arguments(c);
641  expression rfe = expression_undefined; /* Repeat Factor Expression */
642  expression cve = expression_undefined; /* Constant Value Expression */
643  int n = 1; /* Default repeat factor */
644 
645  if(ENTITY_REPEAT_VALUE_P(rf)) {
646  /* pips_assert("The repeat function is called", ENTITY_REPEAT_VALUE_P(rf)); */
647  pips_assert("The repeat function is called with two arguments", gen_length(args)==2);
648 
649  rfe = EXPRESSION(CAR(args));
650  cve = EXPRESSION(CAR(CDR(args)));
651  n = expression_to_int(rfe);
652  }
653  else {
654  cve = vs;
655  }
656 
657  pips_assert("A constant value expression is a call", expression_call_p(cve));
658  *pcve = cve;
659  *pmax_cp += n;
660  }
661  else {
662  pips_internal_error("Call expression expected");
663  }
664  pips_debug(2, "ctp=%d, *pmin_cp=%d, *pmax_cp=%d\n", ctp, *pmin_cp, *pmax_cp);
665  }
666 
667  pips_debug(2, "End for target ctp=%d with window [%d, %d]\n", ctp, *pmin_cp, *pmax_cp);
668 
669  return lcvl;
670 }
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
size_t gen_length(const list l)
Definition: list.c:150
#define pips_internal_error
Definition: misc-local.h:149
#define ENTITY_REPEAT_VALUE_P(e)
int expression_to_int(expression exp)
================================================================
Definition: expression.c:2205
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define expression_undefined
Definition: ri.h:1223
#define call_arguments(x)
Definition: ri.h:711

References call_arguments, call_function, CAR, CDR, ENDP, ENTITY_REPEAT_VALUE_P, EXPRESSION, expression_call_p(), expression_syntax, expression_to_int(), expression_undefined, gen_length(), ParserError(), pips_assert, pips_debug, pips_internal_error, pips_user_warning, POP, and syntax_call.

Referenced by process_value_list().

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

◆ fix_storage()

static bool fix_storage ( reference  r)
static

Variable is in static area or in a user declared common

Variable must be in a user declared common

Variable must be in static area

No need to go down

Definition at line 409 of file procedure.c.

410 {
411  entity v = reference_variable(r);
412 
413  /*
414  if(entity_variable_p(v)) {
415  if(!gen_in_list_p(v, implicit_do_index_set)) {
416  save_initialized_variable(v);
417  }
418  }
419  */
420 
422  pips_debug(8, "Storage for entity %s must be static or made static\n",
423  entity_name(v));
424 
426  entity_storage(v) =
429  StaticArea,
431  NIL)));
432  }
433  else if(storage_ram_p(entity_storage(v))) {
436 
437  if(dynamic_area_p(s)) {
438  if(entity_blockdata_p(m)) {
440  ("Variable %s is declared dynamic in a BLOCKDATA\n",
441  entity_local_name(v));
442  ParserError("fix_storage",
443  "No dynamic variables in BLOCKDATA\n");
444  }
445  else {
446  SaveEntity(v);
447  }
448  }
449  else {
450  /* Variable is in static area or in a user declared common */
451  if(entity_blockdata_p(m)) {
452  /* Variable must be in a user declared common */
453  if(static_area_p(s)) {
455  ("DATA for variable %s declared is impossible:"
456  " it should be declared in a COMMON instead\n",
457  entity_local_name(v));
458  ParserError("fix_storage",
459  "Improper DATA declaration in BLOCKDATA");
460  }
461  }
462  else {
463  /* Variable must be in static area */
464  if(!static_area_p(s)) {
466  ("DATA for variable %s declared in COMMON %s:"
467  " not standard compliant,"
468  " use a BLOCKDATA\n",
470  if(!get_bool_property("PARSER_ACCEPT_ANSI_EXTENSIONS")) {
471  ParserError("fix_storage",
472  "Improper DATA declaration, use a BLOCKDATA"
473  " or set property PARSER_ACCEPT_ANSI_EXTENSIONS");
474  }
475  }
476  }
477  }
478  }
479  else {
480  pips_user_warning("DATA initialization for non RAM variable %s "
481  "(storage tag = %d)\n",
483  ParserError("fix_storage",
484  "DATA statement initializes non RAM variable\n");
485  }
486  }
487  /* No need to go down */
488  return false;
489 }
storage make_storage(enum storage_utype tag, void *val)
Definition: ri.c:2273
ram make_ram(entity a1, entity a2, intptr_t a3, list a4)
Definition: ri.c:1999
void SaveEntity(entity e)
These two functions transform a dynamic variable into a static one.
Definition: declaration.c:178
bool gen_in_list_p(const void *vo, const list lx)
tell whether vo belongs to lx
Definition: list.c:734
static list implicit_do_index_set
Definition: procedure.c:395
#define UNKNOWN_RAM_OFFSET
bool dynamic_area_p(entity aire)
Definition: area.c:68
bool static_area_p(entity aire)
Definition: area.c:77
bool entity_blockdata_p(entity e)
Definition: entity.c:712
#define storage_tag(x)
Definition: ri.h:2515
#define storage_ram_p(x)
Definition: ri.h:2519
#define ram_section(x)
Definition: ri.h:2249
@ is_storage_ram
Definition: ri.h:2492
#define storage_ram(x)
Definition: ri.h:2521
#define storage_undefined_p(x)
Definition: ri.h:2477

References dynamic_area_p(), entity_blockdata_p(), entity_local_name(), entity_name, entity_storage, gen_in_list_p(), get_bool_property(), get_current_module_entity(), implicit_do_index_set, is_storage_ram, make_ram(), make_storage(), module_local_name(), NIL, ParserError(), pips_debug, pips_user_warning, ram_section, reference_variable, SaveEntity(), static_area_p(), StaticArea, storage_ram, storage_ram_p, storage_tag, storage_undefined_p, and UNKNOWN_RAM_OFFSET.

Referenced by process_static_initializations().

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

◆ gather_implicit_indices()

static bool gather_implicit_indices ( call  c)
static

Definition at line 397 of file procedure.c.

398 {
399  entity idf = call_function(c);
400 
401  if(ENTITY_IMPLIEDDO_P(idf)) {
405  }
406  return true;
407 }
list gen_once(const void *vo, list l)
Prepend an item to a list only if it is not already in the list.
Definition: list.c:722
#define ENTITY_IMPLIEDDO_P(e)
#define syntax_reference(x)
Definition: ri.h:2730

References call_arguments, call_function, CAR, ENTITY_IMPLIEDDO_P, EXPRESSION, expression_syntax, gen_once(), implicit_do_index_set, reference_variable, and syntax_reference.

Referenced by process_static_initializations().

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

◆ ghost_variable_entity_p()

bool ghost_variable_entity_p ( entity  e)

Definition at line 292 of file procedure.c.

293 {
295 
297 }
bool entity_is_argument_p(entity e, cons *args)
Definition: arguments.c:150

References entity_is_argument_p(), ghost_variable_entities, list_undefined_p, and pips_assert.

Referenced by NameToFunctionalEntity(), and SafeFindOrCreateEntity().

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

◆ implied_do_reference_number()

static int implied_do_reference_number ( expression  e)
static

forward declaration

Must be an implied DO

local value position

Definition at line 561 of file procedure.c.

562 {
563  /* Must be an implied DO */
566  int lvp = 0; /* local value position */
567 
568  pips_debug(2, "Begin\n");
569 
570  pips_assert("This is an implied DO", (strcmp(entity_local_name(f), IMPLIED_DO_NAME)==0));
571  pips_assert("This is an implied DO", gen_length(args)>=3);
572 
573  MAP(EXPRESSION, se, {
574  int llvp = -1;
575 
576  llvp = expression_reference_number(se);
577 
578  if(llvp>0) {
579  lvp += llvp;
580  }
581  else {
582  lvp = -1;
583  break;
584  }
585  }, CDR(CDR(args)));
586 
587  if(lvp>0) {
588  expression re = EXPRESSION(CAR(CDR(args)));
590  intptr_t c = -1;
591 
592  ifdebug(2)
593  pips_assert("The second argument of an implied do is a range",
595 
596  if(range_count(r, &c)) {
597  lvp *= c;
598  }
599  else {
600  pips_user_warning("Between line %d and %d:\n"
601  "Only constant loop bounds with non-zero increment"
602  " are supported by the PIPS parser in DATA statement\n",
603  line_b_I, line_e_I);
604  lvp = -1;
605  }
606  }
607 
608  pips_debug(2, "End with lvp = %d\n", lvp);
609 
610  return lvp;
611 }
if(!(yy_init))
Definition: genread_lex.c:1029
static int expression_reference_number(expression e)
Definition: procedure.c:494
bool range_count(range r, intptr_t *pcount)
The range count only can be evaluated if the three range expressions are constant and if the incremen...
Definition: eval.c:979
#define syntax_range(x)
Definition: ri.h:2733
#define syntax_range_p(x)
Definition: ri.h:2731
#define intptr_t
Definition: stdint.in.h:294
Polymorphic argument.
Definition: printf-args.h:92
int line_e_I
Definition: parser.c:68
int line_b_I
Indicates where the current instruction (in fact statement) starts and ends in the input file and giv...
Definition: parser.c:68

References call_arguments, call_function, CAR, CDR, entity_local_name(), EXPRESSION, expression_reference_number(), expression_syntax, f(), gen_length(), ifdebug, IMPLIED_DO_NAME, intptr_t, line_b_I, line_e_I, MAP, pips_assert, pips_debug, pips_user_warning, range_count(), syntax_call, syntax_range, and syntax_range_p.

Referenced by expression_reference_number().

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

◆ init_ghost_variable_entities()

void init_ghost_variable_entities ( void  )

procedure.c

Definition at line 69 of file procedure.c.

70 {
73 }

References ghost_variable_entities, list_undefined_p, NIL, and pips_assert.

◆ IsEffectiveFormalParameterP()

bool IsEffectiveFormalParameterP ( entity  f)

Definition at line 1534 of file procedure.c.

1535 {
1537 }

References effective_formal_parameters, entity_is_argument_p(), and f().

Referenced by MakeEntry().

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

◆ LocalToGlobal()

entity LocalToGlobal ( entity  e)

Definition at line 1801 of file procedure.c.

1802 {
1803  return SafeLocalToGlobal(e, type_undefined);
1804 }
entity SafeLocalToGlobal(entity e, type r)
A local entity might have been created but found out later to be global, depending on the order of de...
Definition: procedure.c:1681

References SafeLocalToGlobal(), and type_undefined.

Referenced by MakeEntry(), and MakeExternalFunction().

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

◆ MakeCurrentFunction()

void MakeCurrentFunction ( type  t,
int  msf,
const char *  cfn,
list  lfp 
)

this function creates one entity cf that represents the Fortran function f being analyzed.

if f is a Fortran FUNCTION, a second entity is created; this entity represents the variable that is used in the function body to return a value. both entities share the same name and the type of the result entity is equal to the type of cf's result.

t is the type of the function result if it has been given by the programmer as in INTEGER FUNCTION F(A,B,C)

msf indicates if f is a main, a subroutine or a function.

cf is the current function

lfp is the list of formal parameters

current function

the body of the current function

the second entity, used to store the function result

to split the entity name space between mains, commons, blockdatas and regular modules

full current function name

global entity with conflicting name

Check that there is no such common: This test is obsolete because the standard does not prohibit the use of the same name for a common and a function. However, it is not a good programming practice

if(!type_undefined_p(entity_type(cf)) || ! storage_undefined_p(entity_storage(cf)) || !value_undefined_p(entity_initial(cf)))

Clean up existing local entities in case of a recompilation.

A block data may be declared in an EXTERNAL statement, see Standard 8-9

remove_variable_entity(ce);

Let's hope cf is not an intrinsic

Unfortunately, an intrinsics cannot be redefined, just like a user function or subroutine after editing because intrinsics are not handled like user functions or subroutines. They are not added to the called_modules list of other modules, unless the redefining module is parsed FIRST. There is not mechanism in PIPS to control the parsing order.

set ghost variable entities to NIL

This procedure is called when the whole module declaration statement has been parsed. The formal parameters have already been declared and the ghost variables checked. The call was moved in gram.y, reduction rule for psf_keyword.

init_ghost_variable_entities();

initialize equivalence chain lists to NIL

the intended result type t for a main or a subroutine should be undefined

The parameters part of cf's functional type is not created because the types of formal parameters are not known yet. This is performed later by UpdateFunctionalType().

If a call to the function has been encountered before, it's already typed. However, this information is discarded.

a function has a rom storage

a function has an initial value 'code' that contains an empty block

FI: This NULL string is a catastrophy for the strcmp used later to check the content of the stack. Any string, including the empty string "", would be better. icf is used to link new instructions/statement to the current block. Only the first block is not pushed for syntactic reasons. The later blocks will be pushed for DO's and IF's.

PushBlock(icf, (string) NULL);

No common has yet been declared

Generic areas are created for memory allocation.

Formal parameters are created. Alternate returns can be ignored or substituted.

a result entity is created

esult = FindOrCreateEntity(CurrentPackage, entity_local_name(cf));

CleanLocalEntities() does not remove any entity

Parameters
msfsf
cfnfn
lfpfp

Definition at line 1239 of file procedure.c.

1243 {
1244  entity cf = entity_undefined; /* current function */
1245  instruction icf; /* the body of the current function */
1246  entity result; /* the second entity, used to store the function result */
1247  /* to split the entity name space between mains, commons, blockdatas and regular modules */
1248  string prefix = string_undefined;
1249  string fcfn = string_undefined; /* full current function name */
1250  entity ce = entity_undefined; /* global entity with conflicting name */
1251 
1252  /* Check that there is no such common: This test is obsolete because
1253  * the standard does not prohibit the use of the same name for a
1254  * common and a function. However, it is not a good programming practice
1255  */
1258  COMMON_PREFIX, cfn, NULL),
1260  {
1261  pips_user_warning("global name %s used for a module and for a common\n",
1262  cfn);
1263  /*
1264  ParserError("MakeCurrentFunction",
1265  "Name conflict between a "
1266  "subroutine and/or a function and/or a common\n");
1267  */
1268  }
1269 
1270  if(msf==TK_PROGRAM) {
1271  prefix = MAIN_PREFIX;
1272  }
1273  else if(msf==TK_BLOCKDATA) {
1275  }
1276  else {
1277  prefix = "";
1278  }
1279  fcfn = strdup(concatenate(prefix, cfn, NULL));
1281  free(fcfn);
1282 
1283  /* if(!type_undefined_p(entity_type(cf))
1284  || ! storage_undefined_p(entity_storage(cf))
1285  || !value_undefined_p(entity_initial(cf))) */
1286 
1287  if(!value_undefined_p(entity_initial(cf))) {
1288  if(value_code_p(entity_initial(cf))) {
1289  code c = value_code(entity_initial(cf));
1290  if(!code_undefined_p(c) && !ENDP(code_declarations(c))) {
1291  /* Clean up existing local entities in case of a recompilation. */
1292  CleanLocalEntities(cf);
1293  }
1294  }
1295  }
1296 
1297  ce = FindEntity(TOP_LEVEL_MODULE_NAME, cfn);
1298  if(!entity_undefined_p(ce) && ce!=cf) {
1299  if(!value_undefined_p(entity_initial(cf)) || msf!=TK_BLOCKDATA) {
1300  user_warning("MakeCurrentFunction", "Global name %s used for a function or subroutine"
1301  " and for a %s\n", cfn, msf==TK_BLOCKDATA? "blockdata" : "main");
1302  ParserError("MakeCurrentFunction", "Name conflict\n");
1303  }
1304  else {
1305  /* A block data may be declared in an EXTERNAL statement, see Standard 8-9 */
1306  pips_debug(1, "Entity \"%s\" does not really exist."
1307  " A blockdata is declared in an EXTERNAL statement.",
1308  entity_name(ce));
1309  /* remove_variable_entity(ce); */
1311  }
1312  }
1313 
1314  /* Let's hope cf is not an intrinsic */
1315  if( entity_type(cf) != type_undefined
1316  && intrinsic_entity_p(cf) ) {
1317  user_warning("MakeCurrentFunction",
1318  "Intrinsic %s redefined.\n"
1319  "This is not supported by PIPS. Please rename %s\n",
1321  /* Unfortunately, an intrinsics cannot be redefined, just like a user function
1322  * or subroutine after editing because intrinsics are not handled like
1323  * user functions or subroutines. They are not added to the called_modules
1324  * list of other modules, unless the redefining module is parsed FIRST.
1325  * There is not mechanism in PIPS to control the parsing order.
1326  */
1327  ParserError("MakeCurrentFunction",
1328  "Name conflict between a "
1329  "subroutine and/or a function and an intrinsic\n");
1330  }
1331 
1332  /* set ghost variable entities to NIL */
1333  /* This procedure is called when the whole module declaration
1334  statement has been parsed. The formal parameters have already been
1335  declared and the ghost variables checked. The call was moved in
1336  gram.y, reduction rule for psf_keyword. */
1337  /* init_ghost_variable_entities(); */
1338 
1339  /* initialize equivalence chain lists to NIL */
1340  SetChains();
1341 
1342  if (msf == TK_FUNCTION) {
1343  if (t == type_undefined) {
1344  t = ImplicitType(cf);
1345  }
1346  }
1347  else {
1348  if (t == type_undefined) {
1349  t = make_type(is_type_void, UU);
1350  }
1351  else {
1352  /* the intended result type t for a main or a subroutine should be undefined */
1353  FatalError("MakeCurrentFunction", "bad type\n");
1354  }
1355  }
1356 
1357  /* The parameters part of cf's functional type is not created because
1358  the types of formal parameters are not known yet. This is performed
1359  later by UpdateFunctionalType().
1360 
1361  If a call to the function has been encountered before, it's already
1362  typed. However, this information is discarded. */
1363  if(!type_undefined_p(entity_type(cf))) {
1364  free_type(entity_type(cf));
1365  }
1367 
1368  /* a function has a rom storage */
1370 
1371  /* a function has an initial value 'code' that contains an empty block */
1372  icf = MakeEmptyInstructionBlock();
1373 
1374  /* FI: This NULL string is a catastrophy for the strcmp used later
1375  * to check the content of the stack. Any string, including
1376  * the empty string "", would be better. icf is used to link new
1377  * instructions/statement to the current block. Only the first
1378  * block is not pushed for syntactic reasons. The later blocks
1379  * will be pushed for DO's and IF's.
1380  */
1381  /* PushBlock(icf, (string) NULL); */
1382  PushBlock(icf, "INITIAL");
1383 
1385  entity_initial(cf) =
1387  make_code(NIL, NULL, make_sequence(NIL),NIL,
1389 
1391 
1392  /* No common has yet been declared */
1394 
1395  /* Generic areas are created for memory allocation. */
1396  InitAreas();
1397 
1398  /* Formal parameters are created. Alternate returns can be ignored
1399  * or substituted.
1400  */
1402  (get_string_property("PARSER_SUBSTITUTE_ALTERNATE_RETURNS"));
1404 
1405  if (msf == TK_FUNCTION) {
1406  /* a result entity is created */
1407  /*result = FindOrCreateEntity(CurrentPackage, entity_local_name(cf));*/
1408  /*
1409  result = make_entity(strdup(concatenate(CurrentPackage,
1410  MODULE_SEP_STRING,
1411  module_local_name(cf),
1412  NULL)),
1413  type_undefined,
1414  storage_undefined,
1415  value_undefined);
1416  */
1417  /* CleanLocalEntities() does not remove any entity */
1419  module_local_name(cf));
1421  value_undefined);
1422  AddEntityToDeclarations(result, cf);
1423  }
1424 }
functional make_functional(list a1, type a2)
Definition: ri.c:1109
language make_language_fortran(void)
Definition: ri.c:1250
storage make_storage_rom(void)
Definition: ri.c:2285
value make_value(enum value_utype tag, void *val)
Definition: ri.c:2832
code make_code(list a1, string a2, sequence a3, list a4, language a5)
Definition: ri.c:353
void free_type(type p)
Definition: ri.c:2658
sequence make_sequence(list a)
Definition: ri.c:2125
type make_type(enum type_utype tag, void *val)
Definition: ri.c:2706
void InitAreas()
Definition: declaration.c:100
void DeclareVariable(entity e, type t, list d, storage s, value v)
void DeclareVariable(e, t, d, s, v): update entity e description as declaration statements are encoun...
Definition: declaration.c:670
type ImplicitType(entity e)
This function computes the Fortran implicit type of entity e.
Definition: declaration.c:1311
void initialize_common_size_map()
Definition: declaration.c:947
void SetChains()
initialize chains before each call to the parser
Definition: equivalence.c:76
char * get_string_property(const char *)
void free(void *)
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
#define user_warning(fn,...)
Definition: misc-local.h:262
#define COMMON_PREFIX
Definition: naming-local.h:34
#define MAIN_PREFIX
Definition: naming-local.h:32
#define BLOCKDATA_PREFIX
Definition: naming-local.h:35
#define MODULE_SEP_STRING
Definition: naming-local.h:30
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
void * gen_find_tabulated(const char *, int)
Definition: tabulated.c:218
#define string_undefined
Definition: newgen_types.h:40
#define UU
Definition: newgen_types.h:98
void ScanFormalParameters(entity m, list l)
this function scans the formal parameter list.
Definition: procedure.c:2503
void remove_module_entity(entity m)
Definition: procedure.c:1188
static const char * prefix
entity FindEntity(const char *package, const char *name)
Retrieve an entity from its package/module name and its local name.
Definition: entity.c:1503
entity FindOrCreateEntity(const char *package, const char *local_name)
Problem: A functional global entity may be referenced without parenthesis or CALL keyword in a functi...
Definition: entity.c:1586
bool intrinsic_entity_p(entity e)
Definition: entity.c:1272
void AddEntityToDeclarations(entity, entity)
END_EOLE.
Definition: variable.c:108
#define value_undefined_p(x)
Definition: ri.h:3017
#define value_undefined
Definition: ri.h:3016
#define value_code_p(x)
Definition: ri.h:3065
#define code_undefined_p(x)
Definition: ri.h:758
@ is_value_code
Definition: ri.h:3031
@ is_storage_return
Definition: ri.h:2491
#define entity_undefined_p(x)
Definition: ri.h:2762
#define value_code(x)
Definition: ri.h:3067
@ is_type_void
Definition: ri.h:2904
@ is_type_functional
Definition: ri.h:2901
#define entity_domain
newgen_syntax_domain_defined
Definition: ri.h:410
char * strdup()
#define TK_FUNCTION
Definition: syn_yacc.c:310
#define TK_PROGRAM
Definition: syn_yacc.c:325
#define TK_BLOCKDATA
Definition: syn_yacc.c:284
#define FatalError(f, m)
Definition: syntax-local.h:56
list add_formal_return_code(list fpl)
Update the formal and actual parameter lists by adding the return code variable as last argument.
Definition: return.c:209
void PushBlock(instruction i, string l)
Definition: statement.c:221
instruction MakeEmptyInstructionBlock()
this function creates an empty block
Definition: statement.c:654

References add_formal_return_code(), AddEntityToDeclarations(), BLOCKDATA_PREFIX, CleanLocalEntities(), code_declarations, code_undefined_p, COMMON_PREFIX, concatenate(), CurrentPackage, DeclareVariable(), ENDP, entity_domain, entity_initial, entity_local_name(), entity_name, entity_storage, entity_type, entity_undefined, entity_undefined_p, FatalError, FindEntity(), FindOrCreateEntity(), free(), free_type(), function_body, gen_find_tabulated(), get_string_property(), ImplicitType(), InitAreas(), initialize_common_size_map(), instruction_to_statement(), intrinsic_entity_p(), is_storage_return, is_type_functional, is_type_void, is_value_code, MAIN_PREFIX, make_code(), make_functional(), make_language_fortran(), make_sequence(), make_storage(), make_storage_rom(), make_type(), make_value(), MakeEmptyInstructionBlock(), module_local_name(), MODULE_SEP_STRING, NIL, ParserError(), pips_debug, pips_user_warning, prefix, PushBlock(), remove_module_entity(), ScanFormalParameters(), set_current_module_entity(), SetChains(), strdup(), string_undefined, SubstituteAlternateReturns(), TK_BLOCKDATA, TK_FUNCTION, TK_PROGRAM, TOP_LEVEL_MODULE_NAME, type_undefined, type_undefined_p, user_warning, UU, value_code, value_code_p, value_undefined, and value_undefined_p.

+ Here is the call graph for this function:

◆ MakeEntry()

instruction MakeEntry ( entity  e,
list  lfp 
)

An ENTRY statement is substituted by a labelled continue.

The ENTRY entity is created as in MakeExternalFunction() and MakeCurrentFunction(). list of formal parameters

current module cm

The parser expects an instruction and not a statement. I use a block wrapping to avoid tampering with lab_I.

entity e = FindOrCreateEntity(cmn, en);

result type

current chunk (temporary)

list of effective formal parameters

Name conflicts could be checked here as in MakeCurrentFunction()

Keep track of the effective formal parameters of the current module cm at the first call to MakeEntry and reallocate static variables.

Check if the static area is empty and define a specific common if not.

Too early: StaticArea is not defined yet. Postpone to ProcessEntry. if(area_size(type_area(entity_type(StaticArea)))!=0) { MakeEntryCommon(cm, StaticArea); }

Compute the result type and make sure a functional entity is being used.

In case of previous declaration in the current module

Entity e must not be destroyed if fe is a function because e must carry the result.

In case of previous declaration in the current module

Entry fe may have been encountered earlier and typed from the parameter list

This depends on what has been done in LocalToGlobal and SafeLocalToGlobal

This depends on what has been done in LocalToGlobal and SafeLocalToGlobal

A call site for fe has been encountered in another module

Should now be the normal case...

The entry formal parameters should be removed if they are not formal parameters of the current module... but they are referenced. They cannot be preserved although useless because they may be dimensionned by expressions legal for this entry but not for the current module. They should be removed later when dead code elimination let us know which variables are used by each entry.

Temporarily, the formal parameters of entry fe are declared in cm to keep the code consistent but they are supposedly not added to cm's declarations... because FindOrCreateEntity() does not update declarations. MakeAtom() does not redeclare formal parameters.

Let's assume it works for undefined storages..

Should it really be officially declared?

Remove it from the declaration list

fp may appear in a type statement and/or an executable statement: the information is now lost.

Request some post-processing

Parameters
lfpentry, local to retrieve potential explicit typing

Definition at line 1810 of file procedure.c.

1813 {
1814  entity cm = get_current_module_entity(); /* current module cm */
1815  entity l = make_new_label(cm);
1817  /* The parser expects an instruction and not a statement. I use
1818  * a block wrapping to avoid tampering with lab_I.
1819  */
1821  /* entity e = FindOrCreateEntity(cmn, en); */
1822  entity fe = entity_undefined;
1823  bool is_a_function = entity_function_p(get_current_module_entity());
1824  type rt = type_undefined; /* result type */
1825  list cc = list_undefined; /* current chunk (temporary) */
1826  list lefp = list_undefined; /* list of effective formal parameters */
1827 
1828  pips_debug(1, "Begin for entry %s\n", entity_name(e));
1829 
1830  /* Name conflicts could be checked here as in MakeCurrentFunction() */
1831 
1832  /* Keep track of the effective formal parameters of the current module cm
1833  * at the first call to MakeEntry and reallocate static variables.
1834  */
1835  if(EmptyEntryListsP()) {
1836  MAP(ENTITY, fp, {
1840  }, entity_declarations(cm));
1841 
1842  /* Check if the static area is empty and define a specific common
1843  * if not.
1844  */
1845  /* Too early: StaticArea is not defined yet. Postpone to ProcessEntry.
1846  if(area_size(type_area(entity_type(StaticArea)))!=0) {
1847  MakeEntryCommon(cm, StaticArea);
1848  }
1849  */
1850  }
1851 
1852  /* Compute the result type and make sure a functional entity is being
1853  * used.
1854  */
1855  if(is_a_function) {
1856  rt = MakeResultType(e, type_undefined);
1857  /* In case of previous declaration in the current module */
1858  /* Entity e must not be destroyed if fe is a function because e
1859  * must carry the result.
1860  */
1861  fe = SafeLocalToGlobal(e, rt);
1862  }
1863  else {
1864  rt = make_type(is_type_void, UU);
1865  /* In case of previous declaration in the current module */
1866  fe = LocalToGlobal(e);
1867  }
1868 
1869  lefp = TranslateEntryFormals(fe, lfp);
1870  UpdateFormalStorages(fe, lefp);
1871 
1872  /* Entry fe may have been encountered earlier and typed from the
1873  parameter list */
1874  if(!type_undefined_p(entity_type(fe))) {
1875  free_type(entity_type(fe));
1877  }
1878  TypeFunctionalEntity(fe, rt);
1879  UpdateFunctionalType(fe, lefp);
1880 
1881  /* This depends on what has been done in LocalToGlobal and SafeLocalToGlobal */
1884  }
1885  else {
1886  pips_assert("storage must be rom", storage_rom_p(entity_storage(fe)));
1887  }
1888 
1889  /* This depends on what has been done in LocalToGlobal and SafeLocalToGlobal */
1892  }
1893  else {
1894  value val = entity_initial(fe);
1895  code c = code_undefined;
1896 
1897  if(value_unknown_p(val)) {
1898  /* A call site for fe has been encountered in another module */
1901  }
1902  else {
1903  pips_assert("value is code", value_code_p(val));
1904  c = value_code(entity_initial(fe));
1905  if(code_undefined_p(c)) {
1907  }
1908  else if(ENDP(code_declarations(c))) {
1909  /* Should now be the normal case... */
1910  code_declarations(c) = lefp;
1911  }
1912  else {
1913  pips_internal_error("Code should not (yet) be defined for entry fe...");
1914  }
1915  }
1916  }
1917 
1918  /* The entry formal parameters should be removed if they are not
1919  * formal parameters of the current module... but they are referenced.
1920  * They cannot be preserved although useless because they may be
1921  * dimensionned by expressions legal for this entry but not for the
1922  * current module. They should be removed later when dead code elimination
1923  * let us know which variables are used by each entry.
1924  *
1925  * Temporarily, the formal parameters of entry fe are declared in cm
1926  * to keep the code consistent but they are supposedly not added to
1927  * cm's declarations... because FindOrCreateEntity() does not update
1928  * declarations. MakeAtom() does not redeclare formal parameters.
1929  */
1930  for(cc = lfp; !ENDP(cc); POP(cc)) {
1931  entity fp = ENTITY(CAR(cc));
1932  storage fps = entity_storage(fp);
1933 
1934  if(storage_undefined_p(fps) || !storage_formal_p(fps)) {
1935  /* Let's assume it works for undefined storages.. */
1936  free_storage(fps);
1938  make_formal(cm, 0));
1939  /* Should it really be officially declared? */
1940  if(!IsEffectiveFormalParameterP(fp)) {
1941  /* Remove it from the declaration list */
1942  /*
1943  entity_declarations(cm) =
1944  arguments_rm_entity(entity_declarations(cm), fp);
1945  */
1947  pips_debug(1, "Entity %s removed from declarations for %s\n",
1948  entity_name(fp), module_local_name(cm));
1949  gen_remove(&entity_declarations(cm), fp);
1950  pips_user_warning("Variable %s seems to be used before it is declared"
1951  " as a formal parameter for entry %s. It is legal "
1952  "if it only appears in a type statement.\n",
1953  entity_local_name(fp), entity_name(e));
1954  /* fp may appear in a type statement and/or an
1955  executable statement: the information is now
1956  lost. */
1957  /*
1958  ParserError("MakeEntry",
1959  "Formal parameters of entries cannot appear textually"
1960  " in executable statements before they are declared"
1961  " (Fortran 77 Standard, 15.7.4, pp. 15-13)");
1962  */
1963  }
1964  }
1965  }
1966  }
1967 
1968  /* Request some post-processing */
1969  AddEntryLabel(l);
1970  AddEntryTarget(s);
1971  AddEntryEntity(fe);
1972 
1973  ifdebug(2) {
1974  (void) fprintf(stderr, "Declarations of formal parameters for entry %s:\n",
1975  entity_name(fe));
1977  (void) fprintf(stderr, "Declarations for current module %s:\n",
1978  entity_name(cm));
1980  }
1981 
1982  pips_debug(1, "End for entry %s\n", entity_name(fe));
1983 
1984  return i;
1985 }
void free_storage(storage p)
Definition: ri.c:2231
formal make_formal(entity a1, intptr_t a2)
Definition: ri.c:1067
instruction make_instruction_block(list statements)
Build an instruction block from a list of statements.
Definition: instruction.c:106
void gen_remove(list *cpp, const void *o)
remove all occurences of item o from list *cpp, which is thus modified.
Definition: list.c:685
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
statement make_continue_statement(entity)
Definition: statement.c:953
void AddEntryLabel(entity l)
Definition: procedure.c:1513
type MakeResultType(entity e, type r)
The result type of a function may be carried by e, by r or be implicit.
Definition: procedure.c:1754
entity LocalToGlobal(entity e)
Definition: procedure.c:1801
bool IsEffectiveFormalParameterP(entity f)
Definition: procedure.c:1534
void AddEntryTarget(statement s)
Definition: procedure.c:1518
void AddEffectiveFormalParameter(entity f)
Keep track of the formal parameters for the current module.
Definition: procedure.c:1529
static list TranslateEntryFormals(entity e, list lfp)
list of formal parameters wrongly declared in current module
Definition: procedure.c:1539
void UpdateFormalStorages(entity m, list lfp)
this function check and set if necessary the storage of formal parameters in lfp.
Definition: procedure.c:2522
void AddEntryEntity(entity e)
Definition: procedure.c:1523
void TypeFunctionalEntity(entity fe, type r)
Definition: procedure.c:2257
bool entity_function_p(entity e)
Definition: entity.c:724
entity make_new_label(entity module)
This function returns a new label.
Definition: entity.c:357
#define code_undefined
Definition: ri.h:757
#define value_unknown_p(x)
Definition: ri.h:3077
@ is_storage_formal
Definition: ri.h:2493
#define storage_rom_p(x)
Definition: ri.h:2525

References AddEffectiveFormalParameter(), AddEntryEntity(), AddEntryLabel(), AddEntryTarget(), CAR, code_declarations, code_undefined, code_undefined_p, CONS, dump_arguments(), EmptyEntryListsP(), ENDP, ENTITY, entity_declarations, entity_function_p(), entity_initial, entity_is_argument_p(), entity_local_name(), entity_name, entity_storage, entity_type, entity_undefined, fprintf(), free_storage(), free_type(), gen_remove(), get_current_module_entity(), ifdebug, is_storage_formal, is_type_void, is_value_code, IsEffectiveFormalParameterP(), list_undefined, LocalToGlobal(), make_code(), make_continue_statement(), make_formal(), make_instruction_block(), make_language_fortran(), make_new_label(), make_sequence(), make_storage(), make_storage_rom(), make_type(), make_value(), MakeResultType(), MAP, module_local_name(), NIL, pips_assert, pips_debug, pips_internal_error, pips_user_warning, POP, SafeLocalToGlobal(), STATEMENT, storage_formal_p, storage_rom_p, storage_undefined_p, strdup(), TranslateEntryFormals(), type_undefined, type_undefined_p, TypeFunctionalEntity(), UpdateFormalStorages(), UpdateFunctionalType(), UU, value_code, value_code_p, value_undefined_p, and value_unknown_p.

+ Here is the call graph for this function:

◆ MakeEntryCommon()

static void MakeEntryCommon ( entity  m,
entity  a 
)
static

Static variables in a module with entries must be redeclared as stored in a common in order to be accessible from all modules derived from the entries.

This may create a problem for variables initialized with a DATA for compilers that do not accept multiple initializations of a common variable.

FI: the prefix used to be "_ENTRY_" but this seems to be refused by f77 3.3.5

Make sure that no static variables are aliased because this special cases has not been implemented

Process all variables in a's layout and declare them stored in c

A variable in a common cannot be initialized more than once

Copy a's area in c's area

Do not sort by name or the offset increasing implicit rule is broken: sort_list_of_entities(area_layout(ac));

Reset a's area

Definition at line 1573 of file procedure.c.

1576 {
1577  /* FI: the prefix used to be "_ENTRY_" but this seems to be refused by f77 3.3.5 */
1578  string c_name = strdup(concatenate(COMMON_PREFIX, "ENTRY_",
1579  module_local_name(m), NULL));
1581  area aa = type_area(entity_type(a));
1582  area ac = area_undefined;
1583  list members = list_undefined;
1584 
1585  pips_debug(1, "Begin for static area %s in module %s\n",
1586  entity_name(a), entity_name(m));
1587 
1588  if(ENDP(area_layout(aa))) {
1589  pips_debug(1, "End: no static variables in module %s\n",
1590  entity_name(m));
1591  return;
1592  }
1593 
1594  members = common_members_of_module(a, m, false);
1595  if(ENDP(members)) {
1596  pips_internal_error("No local static variables in module %s: impossible!",
1597  entity_name(m));
1598  }
1599  gen_free_list(members);
1600 
1601  ifdebug(1) {
1602  pips_debug(1, "Static area %s without aliasing in module %s\n",
1603  entity_name(a), entity_name(m));
1604  print_common_layout(stderr, a, true);
1605  pips_debug(1, "Static area %s with aliasing in module %s\n",
1606  entity_name(a), entity_name(m));
1607  print_common_layout(stderr, a, false);
1608  }
1609 
1610  /* Make sure that no static variables are aliased because this special
1611  cases has not been implemented */
1612  MAP(ENTITY, v, {
1613  storage vs = entity_storage(v);
1614 
1615  pips_assert("storage is ram", storage_ram_p(vs));
1616  pips_assert("storage is static", ram_section(storage_ram(vs)) == a);
1617  if(!ENDP(ram_shared(storage_ram(vs)) )) {
1618  pips_user_warning("Static variable %s is aliased with ",
1619  entity_local_name(v));
1621  ParserError("MakeEntryCommon",
1622  "Entries with aliased static variables not yet supported by PIPS\n");
1623  }
1624  }, area_layout(aa));
1625 
1626  if(entity_undefined_p(c)) {
1628  c = MakeCommon(c);
1629  ac = type_area(entity_type(c));
1630  }
1631  else {
1632  pips_internal_error("The scheme to generate a new common name %s"
1633  " for entries in module %s failed",
1634  c_name, module_local_name(m));
1635  }
1636  free(c_name);
1637 
1638  /* Process all variables in a's layout and declare them stored in c */
1639  MAP(ENTITY, v, {
1640  storage vs = entity_storage(v);
1641 
1642  if(value_constant(entity_initial(v))) {
1643  pips_debug(1,
1644  "Initialized variable %s\n", entity_local_name(v));
1645  /* A variable in a common cannot be initialized more than once */
1646  /*
1647  free_value(entity_initial(v));
1648  entity_initial(v) = make_value(is_value_unknown, UU);
1649  */
1650  }
1651 
1652  ram_section(storage_ram(vs)) = c;
1653  }, area_layout(aa));
1654 
1655  /* Copy a's area in c's area */
1656  area_layout(ac) = area_layout(aa);
1657  /* Do not sort by name or the offset increasing implicit rule is
1658  broken: sort_list_of_entities(area_layout(ac)); */
1659  area_size(ac) = area_size(aa);
1660 
1661  /* Reset a's area */
1662  area_layout(aa) = NIL;
1663  area_size(aa) = 0;
1664 
1665  ifdebug(1) {
1666  pips_debug(1, "New common %s for static area %s in module %s\n",
1667  entity_name(c), entity_name(a), entity_name(m));
1668  print_common_layout(stderr, c, true);
1669  }
1670 
1671  pips_debug(1, "End for static area %s in module %s\n",
1672  entity_name(a), entity_name(m));
1673 }
entity MakeCommon(entity e)
MakeCommon: This function creates a common block.
Definition: declaration.c:1047
void print_arguments(list args)
Definition: naming.c:228
void print_common_layout(FILE *fd, entity c, bool debug_p)
Definition: area.c:207
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
list common_members_of_module(entity common, entity module, bool only_primary)
returns the list of entity to appear in the common declaration.
Definition: entity.c:1741
#define area_size(x)
Definition: ri.h:544
#define value_constant(x)
Definition: ri.h:3073
#define area_layout(x)
Definition: ri.h:546
#define type_area(x)
Definition: ri.h:2946
#define ram_shared(x)
Definition: ri.h:2253
#define area_undefined
Definition: ri.h:520

References area_layout, area_size, area_undefined, common_members_of_module(), COMMON_PREFIX, concatenate(), ENDP, ENTITY, entity_initial, entity_local_name(), entity_name, entity_storage, entity_type, entity_undefined_p, FindOrCreateEntity(), free(), gen_free_list(), ifdebug, list_undefined, local_name_to_top_level_entity(), MakeCommon(), MAP, module_local_name(), NIL, ParserError(), pips_assert, pips_debug, pips_internal_error, pips_user_warning, print_arguments(), print_common_layout(), ram_section, ram_shared, storage_ram, storage_ram_p, strdup(), TOP_LEVEL_MODULE_NAME, type_area, and value_constant.

Referenced by ProcessEntry().

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

◆ MakeExternalFunction()

entity MakeExternalFunction ( entity  e,
type  r 
)

Assertion: fe is a (functional) global entity and the type of its result is new_r, or it is a formal functional parameter

a function has a rom storage, except for formal functions

an external function has an unknown initial value, else code would be temporarily undefined which is avoided (theoretically forbidden) in PIPS.

fe is added to CurrentFunction's entities

Parameters
rentity to be turned into external function type of result

Definition at line 2372 of file procedure.c.

2375 {
2376  entity fe = entity_undefined;
2377  type new_r = type_undefined;
2378 
2379  pips_debug(8, "Begin for %s\n", entity_name(e));
2380 
2381  if(entity_blockdata_p(e)) {
2382  pips_debug(8, "End for blockdata %s\n", entity_name(e));
2383  return e;
2384  }
2385 
2386  new_r = MakeResultType(e, r);
2387 
2388  pips_debug(9, "external function %s declared\n", entity_name(e));
2389 
2390  fe = LocalToGlobal(e);
2391 
2392  /* Assertion: fe is a (functional) global entity and the type of its
2393  result is new_r, or it is a formal functional parameter */
2394 
2395  TypeFunctionalEntity(fe, new_r);
2396 
2397  /* a function has a rom storage, except for formal functions */
2398 
2401  else
2402  if (! storage_formal_p(entity_storage(e)))
2404  else {
2405  pips_user_warning("unsupported formal function %s\n",
2406  entity_name(fe));
2407  /*
2408  ParserError("MakeExternalFunction",
2409  "Formal functions are not supported by PIPS.\n"); */
2410  }
2411 
2412  /* an external function has an unknown initial value, else code would
2413  * be temporarily undefined which is avoided (theoretically forbidden)
2414  * in PIPS. */
2415  if(entity_initial(fe) == value_undefined)
2417 
2418  /* fe is added to CurrentFunction's entities */
2420 
2421  pips_debug(8, "End for %s\n", entity_name(fe));
2422 
2423  return fe;
2424 }
value make_value_unknown(void)
Definition: ri.c:2847
#define storage_undefined
Definition: ri.h:2476

References AddEntityToDeclarations(), entity_blockdata_p(), entity_initial, entity_name, entity_storage, entity_undefined, get_current_module_entity(), LocalToGlobal(), make_storage_rom(), make_value_unknown(), MakeResultType(), pips_debug, pips_user_warning, storage_formal_p, storage_undefined, type_undefined, TypeFunctionalEntity(), and value_undefined.

Referenced by DeclareExternalFunction(), MakeAtom(), and MakeCallInst().

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

◆ MakeFormalParameter()

void MakeFormalParameter ( entity  m,
entity  fp,
int  nfp 
)

This function transforms an untyped entity into a formal parameter.

fp is an entity generated by FindOrCreateEntity() for instance, and nfp is its rank in the formal parameter list.

A specific type is used for the return code variable which may be adde by the parser to handle alternate returns. See return.c offset (i.e. rank) of formal parameter

Parameters
fpmodule of formal parameter
nfpformal parameter

Definition at line 2466 of file procedure.c.

2470 {
2471  // pips_assert("type is undefined", entity_type(fp) == type_undefined);
2472  if(!type_undefined_p(entity_type(fp))) {
2473  pips_user_warning("Formal parameter \"%s\" may be used several times\n",
2474  entity_local_name(fp));
2475  ParserError("MakeFormalParameter",
2476  "formal parameter should not be already typed");
2477  }
2478 
2482  make_value_unknown()),
2483  NIL,NIL));
2484  }
2487  }
2488  else {
2489  entity_type(fp) = ImplicitType(fp);
2490  }
2491 
2492  entity_storage(fp) =
2494 
2496 }
basic make_basic(enum basic_utype tag, void *val)
Definition: ri.c:155
variable make_variable(basic a1, list a2, list a3)
Definition: ri.c:2895
bool formal_label_replacement_p(entity)
Definition: variable.c:1797
type MakeTypeVariable(basic, cons *)
BEGIN_EOLE.
Definition: type.c:116
@ is_basic_string
Definition: ri.h:576
@ is_basic_int
Definition: ri.h:571
@ is_type_variable
Definition: ri.h:2900
bool SubstituteAlternateReturnsP()
Definition: return.c:81
bool ReturnCodeVariableP(entity rcv)
Definition: return.c:145

References entity_initial, entity_local_name(), entity_storage, entity_type, formal_label_replacement_p(), ImplicitType(), is_basic_int, is_basic_string, is_storage_formal, is_type_variable, make_basic(), make_formal(), make_storage(), make_type(), make_value_unknown(), make_variable(), MakeTypeVariable(), NIL, ParserError(), pips_user_warning, ReturnCodeVariableP(), SubstituteAlternateReturnsP(), and type_undefined_p.

Referenced by ScanFormalParameters().

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

◆ MakeResultType()

type MakeResultType ( entity  e,
type  r 
)

The result type of a function may be carried by e, by r or be implicit.

A new type structure is allocated, unless r is used as new result type.

e is a function that was implicitly declared as a variable. this may happen in Fortran.

pips_assert("undefined type", r == type_undefined);

The variable may have been typed, for instance implicitly, but then it appears in a CALL statement and its new type is void. Added for formal parameters.

Well... this should be useless because e is already typed. FI: I do not believe copy_type() is necessary in spite of the non orthogonality...

Definition at line 1754 of file procedure.c.

1757 {
1758  type te = entity_type(e);
1759  type new_r = type_undefined;
1760 
1761  if (te != type_undefined) {
1762  if (type_variable_p(te)) {
1763  /* e is a function that was implicitly declared as a variable.
1764  this may happen in Fortran. */
1765  pips_debug(2, "variable --> fonction\n");
1766  /* pips_assert("undefined type", r == type_undefined); */
1767  if(type_undefined_p(r))
1768  new_r = copy_type(te);
1769  else {
1770  /* The variable may have been typed, for instance
1771  implicitly, but then it appears in a CALL statement and
1772  its new type is void. Added for formal parameters. */
1773  pips_assert("The new result type is void", type_void_p(r));
1774  new_r = r;
1775  }
1776  }
1777  else if (type_functional_p(te)) {
1778  /* Well... this should be useless because e is already typed.
1779  * FI: I do not believe copy_type() is necessary in spite of
1780  * the non orthogonality...
1781  */
1782  new_r = functional_result(type_functional(te));
1783  }
1784  else {
1785  pips_internal_error("Unexpected type %s for entity %s",
1786  type_to_string(te), entity_name(e));
1787  }
1788  }
1789  else {
1790  if(type_undefined_p(r)) {
1791  new_r = ImplicitType(e);
1792  }
1793  else {
1794  new_r = r;
1795  }
1796  }
1797  pips_assert("type new_r is defined", !type_undefined_p(new_r));
1798  return new_r;
1799 }
type copy_type(type p)
TYPE.
Definition: ri.c:2655
string type_to_string(const type)
type.c
Definition: type.c:51
#define functional_result(x)
Definition: ri.h:1444
#define type_functional(x)
Definition: ri.h:2952
#define type_void_p(x)
Definition: ri.h:2959
#define type_variable_p(x)
Definition: ri.h:2947

References copy_type(), entity_name, entity_type, functional_result, ImplicitType(), pips_assert, pips_debug, pips_internal_error, type_functional, type_functional_p, type_to_string(), type_undefined, type_undefined_p, type_variable_p, and type_void_p.

Referenced by MakeEntry(), and MakeExternalFunction().

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

◆ NameToFunctionalEntity()

entity NameToFunctionalEntity ( string  name)

Ignore ghost variables, they are not in the current scope

The functional entity must be a formal parameter

The current declaration is wrong and should be fixed later, i.e. by MakeExternalFunction() or MakeCallInst()

It is the name of a blockdata

Parameters
nameame

Definition at line 2217 of file procedure.c.

2218 {
2221  BLOCKDATA_PREFIX, name, NULL),
2222  entity_domain);
2223 
2224  if(entity_undefined_p(f)) {
2227  entity_domain);
2228 
2229  /* Ignore ghost variables, they are *not* in the current scope */
2231 
2232  if(entity_undefined_p(f)) {
2234  }
2237  /* The functional entity must be a formal parameter */
2238  ;
2239  }
2240  else if(storage_undefined_p(entity_storage(f))) {
2241  /* The current declaration is wrong and should be fixed
2242  * later, i.e. by MakeExternalFunction() or MakeCallInst()
2243  */
2244  ;
2245  }
2246  else {
2247  pips_assert("Unexpected kind of functional entity!", true);
2248  }
2249  }
2250  else {
2251  /* It is the name of a blockdata */
2252  ;
2253  }
2254  return f;
2255 }
bool ghost_variable_entity_p(entity e)
Definition: procedure.c:292

References BLOCKDATA_PREFIX, concatenate(), CurrentPackage, entity_domain, entity_storage, entity_undefined, entity_undefined_p, f(), FindOrCreateEntity(), gen_find_tabulated(), ghost_variable_entity_p(), MODULE_SEP_STRING, pips_assert, storage_formal_p, storage_undefined_p, and TOP_LEVEL_MODULE_NAME.

+ Here is the call graph for this function:

◆ process_static_initialization()

static void process_static_initialization ( call  c)
static

Initialized Scalar VariableS

Scalar Value PositionS

Current Variable Position

Value list from the second element on

Reference list, hanging from call to DATA LIST function

DATA LIST function

reference list expression, with call to DATA LIST

Value List, with repeat operator

Look for initialized scalar variables and for their positions in the reference list

Move al to the first value, passing the reference list

A scalar is referenced

0 is returned for call to IO LIST

Process the value list

Definition at line 852 of file procedure.c.

853 {
854  entity ife = call_function(c);
855  list args = call_arguments(c);
856  list isvs = NIL; /* Initialized Scalar VariableS */
857  list svps = NIL; /* Scalar Value PositionS */
858  _int cvp = 0; /* Current Variable Position */
859  list al = args; /* Value list from the second element on */
860  list rl = list_undefined; /* Reference list, hanging from call to DATA LIST function */
861  entity rlf = entity_undefined; /* DATA LIST function */
862  expression rle = expression_undefined; /* reference list expression, with call to DATA LIST */
863  list vl = list_undefined; /* Value List, with repeat operator */
864 
865  pips_debug(2, "Begin with %zd arguments\n", gen_length(args));
866 
867  pips_assert("This is a call to the static initialization function",
869 
870  /* Look for initialized scalar variables and for their positions in the reference list */
871  rle = EXPRESSION(CAR(al));
872  vl = CDR(al); /* Move al to the first value, passing the reference list */
873  pips_assert("The first argument is a call", expression_call_p(rle));
875  pips_assert("This is the DATA LIST function", ENTITY_DATA_LIST_P(rlf));
877 
878  for(; !ENDP(rl); POP(rl)) {
879  int nr = -1;
880  expression e = EXPRESSION(CAR(rl));
881  if(expression_reference_p(e)) {
883 
884  if(entity_scalar_p(v)) {
885  /* A scalar is referenced */
886  if(gen_in_list_p(v, isvs)) {
887  pips_user_warning("Variable %s appears twice in a DATA statement",
888  entity_local_name(v));
889  ParserError("", "Redundant/Conflicting initialization");
890  }
891  nr = 1;
892  pips_debug(2, "Variable %s with value at position %td\n",
893  entity_local_name(v), cvp);
894  isvs = gen_nconc(isvs, CONS(ENTITY, v, NIL));
895  svps = gen_nconc(svps, CONS(INT,cvp, NIL));
896  }
897  else {
899  }
900  }
901  else {
903  }
904  if(nr>=0) { /* 0 is returned for call to IO LIST */
905  cvp += nr;
906  }
907  else {
908  cvp = -1;
909  break;
910  }
911  }
912 
913  ifdebug(2) {
914  list lp = svps;
915  pips_assert("The variable and positions lists have the same length",
916  gen_length(isvs)==gen_length(svps));
917  if(gen_length(isvs)>0) {
918  pips_debug(2, "List of initialized scalar variables with value positions:\n");
919  MAP(ENTITY, v, {
920  int pos = INT(CAR(lp));
921  fprintf(stderr, "Variable %s has value at position %d\n",
922  entity_local_name(v), pos);
923  POP(lp);
924  }, isvs);
925  }
926  pips_debug(2, "The DATA statement is %s decoded (cvp=%td)\n",
927  ((gen_length(isvs)==0)? "not" : ((cvp==-1)? "partially" : "fully")), cvp);
928  }
929 
930  /* Process the value list */
931 
932  if(!ENDP(isvs)) {
933  if(ENDP(vl)) {
934  ParserError("process_static_initialization",
935  "Empty value list in DATA statement\n");
936  }
937  else {
938  process_value_list(vl, isvs, svps);
939  }
940  }
941 
942  pips_debug(2, "End\n");
943 }
@ INT
Definition: atomic.c:48
intptr_t _int
_INT
Definition: newgen_types.h:53
static void process_value_list(list vl, list isvs, list svps)
Definition: procedure.c:809
#define ENTITY_STATIC_INITIALIZATION_P(e)
Fortran DATA management.
#define ENTITY_DATA_LIST_P(e)

References call_arguments, call_function, CAR, CDR, CONS, ENDP, ENTITY, ENTITY_DATA_LIST_P, entity_local_name(), entity_scalar_p(), ENTITY_STATIC_INITIALIZATION_P, entity_undefined, EXPRESSION, expression_call_p(), expression_reference(), expression_reference_number(), expression_reference_p(), expression_syntax, expression_undefined, fprintf(), gen_in_list_p(), gen_length(), gen_nconc(), ifdebug, INT, list_undefined, MAP, NIL, ParserError(), pips_assert, pips_debug, pips_user_warning, POP, process_value_list(), reference_variable, and syntax_call.

Referenced by process_static_initializations().

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

◆ process_static_initializations()

static void process_static_initializations ( )
static

Variables appearing in a static initialization cannot be in the dynamic area, nor in the heap_area nor in the stack_area. They must be moved to the static area if this happens unless they are implied do indices.

Definition at line 945 of file procedure.c.

946 {
947  sequence iseq =
949 
950  /* Variables appearing in a static initialization cannot be in the
951  dynamic area, nor in the heap_area nor in the stack_area. They must
952  be moved to the static area if this happens unless they are implied
953  do indices. */
959 
960  MAP(STATEMENT, is, {
961  if(statement_call_p(is)) {
962  call c = statement_call(is);
964  }
965  else {
966  pips_internal_error("Initialization statements are call statements");
967  }
968  }, sequence_statements(iseq));
969 
970 }
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
call statement_call(statement)
Get the call of a statement.
Definition: statement.c:1406
bool statement_call_p(statement)
Definition: statement.c:364
static void process_static_initialization(call c)
Definition: procedure.c:852
static bool fix_storage(reference r)
Definition: procedure.c:409
static bool gather_implicit_indices(call c)
Definition: procedure.c:397
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
#define reference_domain
newgen_range_domain_defined
Definition: ri.h:338
#define code_initializations(x)
Definition: ri.h:788
#define sequence_statements(x)
Definition: ri.h:2360

References call_domain, code_initializations, entity_initial, fix_storage(), gather_implicit_indices(), gen_free_list(), gen_null(), gen_recurse, get_current_module_entity(), implicit_do_index_set, list_undefined, MAP, NIL, pips_internal_error, process_static_initialization(), reference_domain, sequence_statements, STATEMENT, statement_call(), statement_call_p(), and value_code.

Referenced by EndOfProcedure().

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

◆ process_value_list()

static void process_value_list ( list  vl,
list  isvs,
list  svps 
)
static

Find a value in vl at the monotonically increasing position given in svps for the variable in isvs. All lists are assumed non-empty.

current target position

The current position is a window because of the repeat operator

minimal current position

maximal current position

Current Value List

Current Initialized Variable List

Current Value Expression

Store value

Not enough values in vl

reuse the same value cve

Store value

Definition at line 809 of file procedure.c.

810 {
811  /* Find a value in vl at the monotonically increasing position given in
812  svps for the variable in isvs. All lists are assumed non-empty. */
813  int ctp = -1; /* current target position */
814  /* The current position is a window because of the repeat operator */
815  int min_cp = -1; /* minimal current position */
816  int max_cp = -1; /* maximal current position */
817  list cvp = list_undefined;
818  list cvl = vl; /* Current Value List */
819  list civl = list_undefined; /* Current Initialized Variable List */
820  expression cve = expression_undefined; /* Current Value Expression */
821 
822  for(cvp=svps, civl = isvs;!ENDP(cvp);POP(cvp), POP(civl)) {
823  entity cvar = ENTITY(CAR(civl));
824  ctp = INT(CAR(cvp));
825 
826  if(ctp>max_cp) {
827  cvl = find_target_position(cvl, ctp, &min_cp, &max_cp, &cve);
828  pips_assert("The value window is not empty", min_cp<=max_cp);
829  if(ctp>=min_cp && ctp <= max_cp) {
830  /* Store value */
831  store_initial_value(cvar, cve);
832  }
833  else {
834  /* Not enough values in vl */
835  pips_user_warning("No value in value list for variable %s and the following ones.\n",
836  entity_local_name(cvar));
837  ParserError("process_value_list", "Not enough values for reference list");
838  }
839  }
840  else if(ctp>=min_cp) {
841  /* reuse the same value cve*/
842  /* Store value */
843  store_initial_value(cvar, cve);
844  }
845  else {
846  pips_internal_error("ctp is smaller than the current value window,"
847  " it should have been satisfied earlier\n");
848  }
849  }
850 }
static void store_initial_value(entity var, expression val)
Integer and bool initial values are stored as int, float, string and maybe complex initial values are...
Definition: procedure.c:675
static list find_target_position(list cvl, int ctp, int *pmin_cp, int *pmax_cp, expression *pcve)
Definition: procedure.c:613

References CAR, ENDP, ENTITY, entity_local_name(), expression_undefined, find_target_position(), INT, list_undefined, ParserError(), pips_assert, pips_internal_error, pips_user_warning, POP, and store_initial_value().

Referenced by process_static_initialization().

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

◆ ProcessEntries()

void ProcessEntries ( void  )

To avoid an include of the prettyprint library and/or a compiler warning.

The declarations for cm are likely to be incorrect. They must be synthesized by the prettyprinter.

Regenerate a SOURCE_FILE .f without entries for the module itself

To avoid warnings about column 73 when the code is parsed again

Not ot duplicate DATA statements for static variables and common variables in every entry

Process each entry

Postponed to the_actual_parser() which needs to know entries were encountered

ResetEntries();

Definition at line 2171 of file procedure.c.

2172 {
2174  code c = entity_code(cm);
2175  list ce = NIL;
2176  list cl = NIL;
2177  list ct = NIL;
2178  text txt = text_undefined;
2179  bool line_numbering_p = get_bool_property("PRETTYPRINT_STATEMENT_NUMBER");
2180  bool data_statements_p = get_bool_property("PRETTYPRINT_DATA_STATEMENTS");
2181  /* To avoid an include of the prettyprint library and/or a
2182  compiler warning. */
2183  /* The declarations for cm are likely to be incorrect. They must be
2184  * synthesized by the prettyprinter.
2185  */
2186  free(code_decls_text(c));
2187  code_decls_text(c) = strdup("");
2188  /* Regenerate a SOURCE_FILE .f without entries for the module itself */
2189  /* To avoid warnings about column 73 when the code is parsed again */
2190  set_bool_property("PRETTYPRINT_STATEMENT_NUMBER", false);
2192  make_text_resource_and_free(module_local_name(cm), DBR_SOURCE_FILE, ".f",
2193  txt);
2194 
2195  /* Not ot duplicate DATA statements for static variables and
2196  common variables in every entry */
2197  set_bool_property("PRETTYPRINT_DATA_STATEMENTS", false);
2198 
2199  /* Process each entry */
2200  for(ce = entry_entities, cl = entry_labels, ct = entry_targets;
2201  !ENDP(ce) && !ENDP(cl) && !ENDP(ct); POP(ce), POP(cl), POP(ct)) {
2202  entity e = ENTITY(CAR(ce));
2203  entity l = ENTITY(CAR(cl));
2204  statement t = STATEMENT(CAR(ct));
2205 
2206  pips_assert("Target and label match", l==statement_label(t));
2207 
2208  ProcessEntry(cm, e, t);
2209  }
2210  set_bool_property("PRETTYPRINT_STATEMENT_NUMBER", line_numbering_p);
2211  set_bool_property("PRETTYPRINT_DATA_STATEMENTS", data_statements_p);
2212  /* Postponed to the_actual_parser() which needs to know entries were
2213  encountered */
2214  /* ResetEntries(); */
2215 }
text text_named_module(entity, entity, statement)
bool make_text_resource_and_free(const char *, const char *, const char *, text)
Definition: print.c:82
static void ProcessEntry(entity cm, entity e, statement t)
Definition: procedure.c:2036
void set_bool_property(const char *, bool)
code entity_code(entity e)
Definition: entity.c:1098
#define statement_label(x)
Definition: ri.h:2450
#define code_decls_text(x)
Definition: ri.h:786
#define text_undefined
Definition: text.h:91

References CAR, code_decls_text, ENDP, ENTITY, entity_code(), entry_entities, entry_labels, entry_targets, free(), get_bool_property(), get_current_module_entity(), get_current_module_statement(), make_text_resource_and_free(), module_local_name(), NIL, pips_assert, POP, ProcessEntry(), set_bool_property(), STATEMENT, statement_label, strdup(), text_named_module(), and text_undefined.

Referenced by EndOfProcedure().

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

◆ ProcessEntry()

static void ProcessEntry ( entity  cm,
entity  e,
statement  t 
)
static

so as not to compute anything before the debugging message is printed out

Compute the proper declaration list, without formal parameters from cm and with formal parameters from e

Collect local and global variables of cm that may be visible from entry e

Try to get rid of unreachable statements which may contain references to formal parameters undeclared in the current entry an obtain a clean entry statement (ces).

By default we use the controlizer that is activated according to pipsmake...

...but we can change it according to special environment variables if they are defined:

Compute an external representation of entry statement es for entry e. Cheat with the declarations because of text_named_module().

DATA statements should not be replicated in each entry code

give the entry a user file.

Definition at line 2036 of file procedure.c.

2040 {
2041  statement es = statement_undefined; /* so as not to compute
2042  anything before the
2043  debugging message is
2044  printed out */
2046  list decls = list_undefined;
2048  text txt = text_undefined;
2049  bool line_numbering_p = false;
2050 
2051  pips_debug(1, "Begin for entry %s of module %s\n",
2052  entity_name(e), module_local_name(cm));
2053 
2056  }
2057 
2058  es = BuildStatementForEntry(cm, e, t);
2059 
2060  /* Compute the proper declaration list, without formal parameters from cm
2061  * and with formal parameters from e
2062  */
2063 
2064  /* Collect local and global variables of cm that may be visible from entry e */
2065  decls = NIL;
2066  MAP(ENTITY, v, {
2067  if(!storage_formal_p(entity_storage(v))) {
2068  decls = arguments_add_entity(decls, v);
2069  }
2070  }, entity_declarations(cm));
2071 
2072  ifdebug(2) {
2073  (void) fprintf(stderr, "Declarations inherited from module %s:\n",
2074  module_local_name(cm));
2076  (void) fprintf(stderr, "Declarations of formal parameters for entry %s:\n",
2077  module_local_name(e));
2079  }
2080 
2081  /* Try to get rid of unreachable statements which may contain references
2082  * to formal parameters undeclared in the current entry an obtain a clean
2083  * entry statement (ces).
2084  */
2085  /* By default we use the controlizer that is activated according to
2086  pipsmake... */
2087  bool use_new_controlizer_p =
2088 #ifdef BUILDER_NEW_CONTROLIZER
2089  active_phase_p(BUILDER_NEW_CONTROLIZER);
2090 #else
2091  false;
2092 #endif // BUILDER_NEW_CONTROLIZER
2093  /* ...but we can change it according to special environment variables if
2094  they are defined: */
2095  use_new_controlizer_p |=
2096  (getenv(USE_NEW_CONTROLIZER_ENV_VAR_NAME) != NULL);
2097  use_new_controlizer_p &=
2098  (getenv(USE_OLD_CONTROLIZER_ENV_VAR_NAME) == NULL);
2099 
2100  if (use_new_controlizer_p)
2101  ces = hcfg(es);
2102  else
2105  MAKE_ORDERING(0,1),
2108  control_graph(es)),
2111 
2112  /* Compute an external representation of entry statement es for entry e.
2113  * Cheat with the declarations because of text_named_module().
2114  */
2116  decls = list_undefined;
2117 
2118  ifdebug(2) {
2119  (void) fprintf(stderr, "Declarations of all variables for entry %s:\n",
2120  module_local_name(e));
2122  }
2123 
2124  decls = entity_declarations(cm);
2126  /* DATA statements should not be replicated in each entry code */
2129 
2130  ifdebug(1) {
2131  fprint_environment(stderr, cm);
2132  }
2133 
2134  line_numbering_p = get_bool_property("PRETTYPRINT_STATEMENT_NUMBER");
2135  set_bool_property("PRETTYPRINT_STATEMENT_NUMBER", false);
2136  txt = text_named_module(e, cm, ces);
2137  set_bool_property("PRETTYPRINT_STATEMENT_NUMBER", line_numbering_p);
2138 
2139  entity_declarations(cm) = decls;
2140  decls = list_undefined;
2143 
2144  pips_assert("statement ces is consistent", statement_consistent_p(ces));
2145 
2146  pips_assert("statement for cm is consistent",
2148 
2149  /* */
2150  make_text_resource_and_free(module_local_name(e), DBR_SOURCE_FILE, ".f",
2151  txt);
2152 
2153  pips_assert("statement for cm is consistent",
2155 
2156  free_statement(ces);
2157 
2158  /* give the entry a user file.
2159  */
2160  DB_PUT_MEMORY_RESOURCE(DBR_USER_FILE, module_local_name(e),
2161  strdup(db_get_memory_resource(DBR_USER_FILE, module_local_name(cm), true)));
2162 
2163  pips_assert("statement for cm is consistent",
2165 
2166  pips_debug(1, "End for entry %s of module %s\n",
2167  entity_name(e), module_local_name(cm));
2168 
2169 }
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
bool active_phase_p(const char *phase)
Definition: activate.c:80
#define USE_OLD_CONTROLIZER_ENV_VAR_NAME
The name of the one to force the use of the old controlizer:
Definition: control-local.h:35
#define USE_NEW_CONTROLIZER_ENV_VAR_NAME
– control.h
Definition: control-local.h:33
void unspaghettify_statement(statement)
The real entry point of unspaghettify:
unstructured control_graph(statement)
CONTROL_GRAPH returns the control graph of the statement ST.
statement hcfg(statement)
Compute the hierarchical control flow graph (HCFG) of a statement.
Definition: controlizer.c:2621
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
static statement init_stmt
static statement BuildStatementForEntry(entity cm, entity e, statement t)
Build an entry version of the current module statement.
Definition: procedure.c:1989
static void MakeEntryCommon(entity m, entity a)
Static variables in a module with entries must be redeclared as stored in a common in order to be acc...
Definition: procedure.c:1573
#define STATEMENT_NUMBER_UNDEFINED
default values
#define MAKE_ORDERING(u, s)
On devrait utiliser Newgen pour cela, mais comme on ne doit pas les utiliser directement (mais via st...
#define empty_comments
Empty comments (i.e.
entity entity_empty_label(void)
Definition: entity.c:1105
extensions empty_extensions(void)
extension.c
Definition: extension.c:43
@ is_instruction_unstructured
Definition: ri.h:1475

References active_phase_p(), area_size, arguments_add_entity(), BuildStatementForEntry(), code_initializations, control_graph(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, dump_arguments(), empty_comments, empty_extensions(), ENTITY, entity_declarations, entity_empty_label(), entity_initial, entity_name, entity_storage, entity_type, fprint_environment(), fprintf(), free_statement(), gen_nconc(), get_bool_property(), get_current_module_statement(), hcfg(), ifdebug, init_stmt, is_instruction_unstructured, list_undefined, make_instruction(), MAKE_ORDERING, make_statement(), make_synchronization_none(), make_text_resource_and_free(), MakeEntryCommon(), MAP, module_local_name(), NIL, pips_assert, pips_debug, sequence_statements, set_bool_property(), statement_consistent_p(), STATEMENT_NUMBER_UNDEFINED, statement_undefined, StaticArea, storage_formal_p, strdup(), text_named_module(), text_undefined, type_area, unspaghettify_statement(), USE_NEW_CONTROLIZER_ENV_VAR_NAME, USE_OLD_CONTROLIZER_ENV_VAR_NAME, and value_code.

Referenced by ProcessEntries().

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

◆ reify_ghost_variable_entity()

void reify_ghost_variable_entity ( entity  e)

It is possible to change one's mind and effectively use an entity which was previously assumed useless.

Definition at line 284 of file procedure.c.

285 {
289 }
cons * arguments_rm_entity(cons *a, entity e)
Definition: arguments.c:94

References arguments_rm_entity(), entity_is_argument_p(), ghost_variable_entities, list_undefined_p, and pips_assert.

Referenced by CheckLeftHandSide().

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

◆ remove_from_called_modules()

void remove_from_called_modules ( entity  e)

macros are added, although they should not have been.

Definition at line 354 of file procedure.c.

355 {
356  bool found = false;
357  list l = called_modules;
358  const char* name = module_local_name(e);
359 
360  if (!called_modules) return;
361 
362  if (same_string_p(name, STRING(CAR(called_modules)))) {
364  found = true;
365  } else {
366  list lp = called_modules;
367  l = CDR(called_modules);
368 
369  for(; !ENDP(l); POP(l), POP(lp)) {
370  if (same_string_p(name, STRING(CAR(l)))) {
371  CDR(lp) = CDR(l);
372  found = true;
373  break;
374  }
375  }
376  }
377 
378  if (found) {
379  pips_debug(3, "removing %s from callees\n", entity_name(e));
380  CDR(l) = NIL;
381  free(STRING(CAR(l)));
382  gen_free_list(l);
383  }
384 }
#define same_string_p(s1, s2)

References called_modules, CAR, CDR, ENDP, entity_name, free(), gen_free_list(), module_local_name(), NIL, pips_debug, POP, same_string_p, and STRING.

Referenced by parser_close_macros_support().

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

◆ remove_ghost_variable_entities()

void remove_ghost_variable_entities ( bool  substitute_p)

The debugging message must use the variable name before it is freed

We already are in ParserError()! Too bad for the memory leak

Parameters
substitute_pubstitute_p

Definition at line 206 of file procedure.c.

207 {
209  MAP(ENTITY, e,
210  {
211  /* The debugging message must use the variable name before it is freed
212  */
213  pips_debug(1, "entity '%s'\n", entity_name(e));
214  pips_assert("Entity e is defined and has type \"variable\" if substitution is required\n",
215  !substitute_p
216  || (!entity_undefined_p(e)
219  user_warning("remove_ghost_variable_entities",
220  "Entity \"%s\" does not really exist but appears"
221  " in an equivalence chain!\n",
222  entity_name(e));
223  if(!ParserError("remove_ghost_variable_entities",
224  "Cannot remove still accessible ghost variable\n")) {
225  /* We already are in ParserError()! Too bad for the memory leak */
227  return;
228  }
229  }
230  else {
232 
233  if(entity_undefined_p(fe)) {
234  pips_assert("Entity fe cannot be undefined", false);
235  }
236  else if(type_undefined_p(entity_type(fe))) {
237  pips_assert("Type for entity fe cannot be undefined", false);
238  }
239  else if(type_functional_p(entity_type(fe))) {
241 
242 
243  /*
244  if(intrinsic_entity_p(fe)) {
245  user_warning("remove_ghost_variable_entities",
246  "Intrinsic %s is probably declared in a strange useless way\n",
247  module_local_name(fe));
248  }
249  */
250 
251 
252  if(substitute_p) {
253  pips_debug(1,
254  "Start substitution of variable %s by module %s\n",
255  entity_name(e), entity_name(fe));
257  pips_debug(1,
258  "End for substitution of variable %s by module %s\n",
259  entity_name(e), entity_name(fe));
260  }
261  }
262  else {
263  pips_assert("Type t for entity fe should be functional", false);
264  }
265 
267  }
268  pips_debug(1, "destroyed\n");
269  },
271 
273 }
bool entity_in_equivalence_chains_p(entity e)
Definition: equivalence.c:403
void substitute_ghost_variable_in_statement(statement stmt, entity v, entity f)
Definition: procedure.c:139
void remove_variable_entity(entity)
Definition: variable.c:1306
Definition: statement.c:54

References ENTITY, entity_in_equivalence_chains_p(), entity_local_name(), entity_name, entity_type, entity_undefined_p, function_body, ghost_variable_entities, list_undefined, list_undefined_p, local_name_to_top_level_entity(), MAP, ParserError(), pips_assert, pips_debug, remove_variable_entity(), substitute_ghost_variable_in_statement(), type_functional_p, type_undefined_p, type_variable_p, and user_warning.

Referenced by AbortOfProcedure(), and EndOfProcedure().

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

◆ remove_module_entity()

void remove_module_entity ( entity  m)

It is assumed that neither variables nor areas have been declared in m but that m may have been declared by EXTERNAL in other modules.

Definition at line 1188 of file procedure.c.

1189 {
1190  /* It is assumed that neither variables nor areas have been declared in m
1191  * but that m may have been declared by EXTERNAL in other modules.
1192  */
1193  gen_array_t modules = db_get_module_list();
1194  int module_list_length = gen_array_nitems(modules);
1195  int i = 0;
1196 
1197  for(i = 0; i < module_list_length; i++) {
1199 
1200  if(!entity_undefined_p(om)) {
1201  value v = entity_initial(om);
1202 
1203  if(!value_undefined_p(v) && !value_unknown_p(v)) {
1204  code c = value_code(v);
1205 
1206  if(!code_undefined_p(c)) {
1207  ifdebug(1) {
1208  if(gen_in_list_p(m, code_declarations(c))) {
1209  pips_debug(1,
1210  "Declaration of module %s removed from %s's declarations",
1211  entity_name(m), entity_name(om));
1212  }
1213  }
1214  gen_remove(&code_declarations(c), m);
1215  }
1216  }
1217  }
1218  }
1219  gen_array_full_free(modules);
1220  free_entity(m);
1221 }
size_t gen_array_nitems(const gen_array_t a)
Definition: array.c:131
void gen_array_full_free(gen_array_t a)
Definition: array.c:77
void * gen_array_item(const gen_array_t a, size_t i)
Definition: array.c:143
gen_array_t db_get_module_list(void)
Get an array of all the modules (functions, procedures and compilation units) of a workspace.
Definition: database.c:1266

References code_declarations, code_undefined_p, db_get_module_list(), entity_initial, entity_name, entity_undefined_p, free_entity(), gen_array_full_free(), gen_array_item(), gen_array_nitems(), gen_in_list_p(), gen_remove(), ifdebug, local_name_to_top_level_entity(), pips_debug, value_code, value_undefined_p, and value_unknown_p.

Referenced by MakeCurrentFunction().

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

◆ ResetEntries()

void ResetEntries ( void  )

Definition at line 1458 of file procedure.c.

References effective_formal_parameters, entry_entities, entry_labels, entry_targets, gen_free_list(), and NIL.

Referenced by the_actual_parser().

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

◆ SafeLocalToGlobal()

entity SafeLocalToGlobal ( entity  e,
type  r 
)

A local entity might have been created but found out later to be global, depending on the order of declaration statements (see MakeExternalFunction()).

The local entity e is (marked as) destroyed and replaced by functional entity fe.

Should we anticipate the value code, since we know it has to be a value code for a function and it may be tested later after the parsing phase of the caller but before the parsing phase of the callee, or should we wait till the code is really known?

entity_initial(fe) = make_value(is_value_unknown, UU);

FI: I need to destroy a virtual entity which does not appear in the program and wich was temporarily created by the parser when it recognized a name; however, I've no way to know if the same entity does not appear for good somewhere else in the code; does the Fortran standard let you write: LOG = LOG(3.) If yes, PIPS will core dump... PIPS also core dumps with ALOG(ALOG(X))... (8 July 1993)

remove_variable_entity(e);

ParserError("LocalToGlobal", "Formal functional parameters are not supported " "by PIPS.\n");

Definition at line 1681 of file procedure.c.

1682 {
1683  entity fe = entity_undefined;
1684 
1685  if(!top_level_entity_p(e)) {
1686  storage s = entity_storage(e);
1687  if(s == storage_undefined || storage_ram_p(s)) {
1688 
1690  entity_local_name(e));
1693  }
1694  else if(!storage_rom_p(entity_storage(fe))) {
1695  FatalError("SafeLocalToGlobal",
1696  "Unexpected storage class for top level entity\n");
1697  }
1699  /* Should we anticipate the value code, since we know it has
1700  to be a value code for a function and it may be tested
1701  later after the parsing phase of the caller but before
1702  the parsing phase of the callee, or should we wait till
1703  the code is really known? */
1704  /* entity_initial(fe) = make_value(is_value_unknown, UU); */
1708  }
1709 
1710  pips_debug(1, "external function %s re-declared as %s\n",
1711  entity_name(e), entity_name(fe));
1712  /* FI: I need to destroy a virtual entity which does not
1713  * appear in the program and wich was temporarily created by
1714  * the parser when it recognized a name; however, I've no way
1715  * to know if the same entity does not appear for good
1716  * somewhere else in the code; does the Fortran standard let
1717  * you write: LOG = LOG(3.) If yes, PIPS will core dump...
1718  * PIPS also core dumps with ALOG(ALOG(X))... (8 July 1993) */
1719  /* remove_variable_entity(e); */
1720  if(type_undefined_p(r)) {
1722  pips_debug(1, "entity %s to be destroyed\n", entity_name(e));
1723  }
1724  else {
1725  pips_debug(1, "entity %s to be preserved to carry function result\n",
1726  entity_name(e));
1727  }
1728  }
1729  else if(storage_formal_p(s)){
1730  pips_user_warning("Variable %s is a formal functional parameter.\n"
1731  "They are not (yet) supported by PIPS.\n",
1732  entity_name(e));
1733  /* ParserError("LocalToGlobal",
1734  "Formal functional parameters are not supported "
1735  "by PIPS.\n"); */
1736  fe = e;
1737  }
1738  else {
1739  pips_internal_error("entity %s has an unexpected storage %d",
1740  entity_name(e), storage_tag(s));
1741  }
1742  }
1743  else {
1744  fe = e;
1745  }
1746  pips_assert("Entity is global or it is a formal functional parameter",
1748  return fe;
1749 }
void add_ghost_variable_entity(entity e)
Definition: procedure.c:275
bool top_level_entity_p(entity e)
Check if the scope of entity e is global.
Definition: entity.c:1130
@ is_storage_rom
Definition: ri.h:2494

References add_ghost_variable_entity(), entity_initial, entity_local_name(), entity_name, entity_storage, entity_undefined, FatalError, FindOrCreateEntity(), is_storage_rom, is_value_code, make_code(), make_language_fortran(), make_sequence(), make_storage(), make_value(), NIL, pips_assert, pips_debug, pips_internal_error, pips_user_warning, storage_formal_p, storage_ram_p, storage_rom_p, storage_tag, storage_undefined, storage_undefined_p, strdup(), top_level_entity_p(), TOP_LEVEL_MODULE_NAME, type_undefined_p, UU, and value_undefined_p.

Referenced by LocalToGlobal(), and MakeEntry().

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

◆ ScanFormalParameters()

void ScanFormalParameters ( entity  m,
list  l 
)

this function scans the formal parameter list.

each formal parameter is created with an implicit type, and then is added to CurrentFunction's declarations.

le parametre formel

son rang dans la liste

Definition at line 2503 of file procedure.c.

2504 {
2505  list pc;
2506  entity fp; /* le parametre formel */
2507  int nfp; /* son rang dans la liste */
2508 
2509  FormalParameters = l;
2510 
2511  for (pc = l, nfp = 1; pc != NULL; pc = CDR(pc), nfp += 1) {
2512  fp = ENTITY(CAR(pc));
2513 
2514  MakeFormalParameter(m, fp, nfp);
2515 
2516  AddEntityToDeclarations(fp, m);
2517  }
2518 }
void MakeFormalParameter(entity m, entity fp, int nfp)
This function transforms an untyped entity into a formal parameter.
Definition: procedure.c:2466

References AddEntityToDeclarations(), CAR, CDR, ENTITY, FormalParameters, and MakeFormalParameter().

Referenced by MakeCurrentFunction().

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

◆ store_initial_value()

static void store_initial_value ( entity  var,
expression  val 
)
static

Integer and bool initial values are stored as int, float, string and maybe complex initial values are stored as entities.

Type coercion should be implemented as required in the Fortran standard.

type val_t = type_of_expression(val);

variable val_vt = type_variable(val_t);

to be freed

The semantics of expression_constant_p() is a call to a constant entity and not a constant expression(), i.e. an expression whose terms are all recursively constant

pips_assert("val is a constant expression", expression_constant_p(val));

return;

Type coercion

Voir avec Fabien les procedures de Son, type_this_chunk() et typing_of_expressions()

Has an initialization already been defined for var?

An evaluation function should evaluate any well-typed expression and return a value. Find below a very limited evaluation procedure for backward compatibility with PIPS previous implementation for integer expressions

Storage if a proper initial value has been found

Is there a leading unary minus?

For real and complex, I should allocate "-f" and forget about calls to unary minus

Definition at line 675 of file procedure.c.

676 {
677  type var_t = entity_type(var);
678  /* type val_t = type_of_expression(val); */
679  variable var_vt = type_variable(var_t);
680  basic var_bt = variable_basic(var_vt);
681  /* variable val_vt = type_variable(val_t); */
682  expression coerced_val = expression_undefined;
683  basic val_bt = basic_of_expression(val); /* to be freed */
684  value fv = value_undefined;
685 
686  ifdebug(2) {
687  pips_debug(2, "Begin for variable %s and expression\n",
688  entity_local_name(var));
689  print_expression(val);
690 
691  pips_assert("var is a scalar variable", entity_scalar_p(var));
692  /* The semantics of expression_constant_p() is a call to a constant
693  entity and not a constant expression(), i.e. an expression whose
694  terms are all recursively constant */
695  /* pips_assert("val is a constant expression", expression_constant_p(val)); */
696  }
697 
698  /* return; */
699 
700  /* Type coercion */
701  if(!basic_equal_p(var_bt, val_bt)) {
702  pips_user_warning("Type coercion needed for variable %s and its DATA expression value\n",
703  entity_local_name(var));
704  print_expression(val);
705  coerced_val = expression_undefined;
706  /* Voir avec Fabien les procedures de Son, type_this_chunk() et typing_of_expressions() */
707  }
708  else {
709  coerced_val = val;
710  }
711 
712  /* Has an initialization already been defined for var? */
713  if(!value_unknown_p(entity_initial(var))) {
714  value v = entity_initial(var);
715  constant c = value_constant(v);
716 
717  pips_assert("value must be constant", value_constant_p(v));
718  pips_assert("constant must be int or call",
720  pips_user_warning("Redefinition of the DATA value for variable %s\n",
721  entity_local_name(var));
722  pips_user_warning("Defined with value %s and redefined by expression\n",
723  constant_int_p(c)?
724  i2a(constant_int(c))
726  print_expression(val);
727  ParserError("store_initial_value", "Conflicting DATA statements");
728  }
729  else {
732  }
733 
734  /* An evaluation function should evaluate any well-typed expression and
735  return a value. Find below a very limited evaluation procedure for
736  backward compatibility with PIPS previous implementation for integer
737  expressions */
738 
739  /* Storage if a proper initial value has been found */
740  if(!expression_undefined_p(coerced_val)) {
741  _int b = -1;
742  int sign = 1;
743  call c = syntax_call(expression_syntax(coerced_val));
744  entity f = call_function(c);
745 
746  pips_assert("The constant value expression is a CALL",
747  expression_call_p(coerced_val));
748 
749  /* Is there a leading unary minus? */
750  if(ENTITY_UNARY_MINUS_P(f)) {
751  sign = -1;
752  coerced_val = EXPRESSION(CAR(call_arguments(c)));
753  pips_assert("The constant value expression is still a CALL",
754  expression_call_p(coerced_val));
755  c = syntax_call(expression_syntax(coerced_val));
756  f = call_function(c);
757  }
758 
759  switch(basic_tag(var_bt)) {
760  case is_basic_int:
761  sscanf(entity_local_name(f), "%td", &b);
763  make_constant(is_constant_int, (value *) (sign*b)));
764  break;
765  case is_basic_logical:
766  if(ENTITY_TRUE_P(f)) {
767  b = 1;
768  }
769  else if(ENTITY_FALSE_P(f)) {
770  b = 0;
771  }
772  else{
773  pips_user_warning("LOGICAL variable %s cannot be initialized with expression",
774  entity_local_name(var));
775  print_expression(coerced_val);
776  ParserError("store_initial_value", "Illegal initialization of a LOGICAL variable");
777  }
780  break;
781  case is_basic_float:
782  case is_basic_complex:
783  case is_basic_string:
784  if(sign==1) {
787  }
788  else {
789  /* For real and complex, I should allocate "-f" and forget about
790  calls to unary minus */
792  }
793  break;
794  case is_basic_overloaded:
795  pips_internal_error("A Fortran variable cannot have the OVERLOADED internal type");
796  break;
797  default:
798  pips_internal_error("Unexpected basic tag=%d", basic_tag(var_bt));
799  break;
800  }
801  }
802  else {
804  }
805  entity_initial(var) = fv;
806  free_basic(val_bt);
807 }
constant make_constant(enum constant_utype tag, void *val)
Definition: ri.c:406
void free_basic(basic p)
Definition: ri.c:107
void free_value(value p)
Definition: ri.c:2787
char * i2a(int)
I2A (Integer TO Ascii) yields a string for a given Integer.
Definition: string.c:121
void print_expression(expression e)
no file descriptor is passed to make is easier to use in a debugging stage.
Definition: expression.c:58
#define ENTITY_UNARY_MINUS_P(e)
#define ENTITY_TRUE_P(e)
#define ENTITY_FALSE_P(e)
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
bool basic_equal_p(basic, basic)
Definition: type.c:927
@ is_basic_float
Definition: ri.h:572
@ is_basic_overloaded
Definition: ri.h:574
@ is_basic_logical
Definition: ri.h:573
@ is_basic_complex
Definition: ri.h:575
#define constant_int(x)
Definition: ri.h:850
#define basic_tag(x)
Definition: ri.h:613
@ is_constant_int
Definition: ri.h:817
@ is_constant_call
Definition: ri.h:821
@ is_value_unknown
Definition: ri.h:3035
@ is_value_constant
Definition: ri.h:3033
#define value_constant_p(x)
Definition: ri.h:3071
#define constant_int_p(x)
Definition: ri.h:848
#define constant_call_p(x)
Definition: ri.h:860
#define expression_undefined_p(x)
Definition: ri.h:1224
#define constant_call(x)
Definition: ri.h:862
int var_t
Type of variables.

References basic_equal_p(), basic_of_expression(), basic_tag, call_arguments, call_function, CAR, constant_call, constant_call_p, constant_int, constant_int_p, ENTITY_FALSE_P, entity_initial, entity_local_name(), entity_scalar_p(), ENTITY_TRUE_P, entity_type, ENTITY_UNARY_MINUS_P, EXPRESSION, expression_call_p(), expression_syntax, expression_undefined, expression_undefined_p, f(), free_basic(), free_value(), i2a(), ifdebug, is_basic_complex, is_basic_float, is_basic_int, is_basic_logical, is_basic_overloaded, is_basic_string, is_constant_call, is_constant_int, is_value_constant, is_value_unknown, make_constant(), make_value(), ParserError(), pips_assert, pips_debug, pips_internal_error, pips_user_warning, print_expression(), syntax_call, type_variable, UU, value_constant, value_constant_p, value_undefined, value_unknown_p, and variable_basic.

Referenced by process_value_list().

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

◆ substitute_ghost_variable_in_expression()

void substitute_ghost_variable_in_expression ( expression  expr,
entity  v,
entity  f 
)

It is assumed that v and f are defined entities and that v is of type variable and f of type functional.

ParserError() is going to request ghost variable substitution recursively and we do not want this to happen because it is going to fail again. Well, substitution won't be tried from AbortOfProcedure()...

ghost_variable_entities = NIL;

ParserError("substitute_ghost_variable_in_expression", "Functional parameters are not (yet) supported by PIPS\n");

Parameters
exprxpr

Definition at line 75 of file procedure.c.

79 {
80  /* It is assumed that v and f are defined entities and that v is of
81  type variable and f of type functional. */
82  syntax s = expression_syntax(expr);
84  range rng = range_undefined;
85  call c = call_undefined;
86 
87  ifdebug(8) {
88  pips_debug(8, "Begin for expression: ");
89  print_expression(expr);
90  }
91 
92  switch(syntax_tag(s)) {
94  ref = syntax_reference(s);
95  if(reference_variable(ref)==v) {
96  pips_debug(1,
97  "Reference to formal functional entity %s to be substituted\n",
98  entity_name(f));
99  /* ParserError() is going to request ghost variable
100  substitution recursively and we do not want this to happen
101  because it is going to fail again. Well, substitution won't be
102  tried from AbortOfProcedure()... */
103  /* ghost_variable_entities = NIL; */
105  "Functional variable %s is used as an actual argument\n"
106  "This is not yet fully supported by PIPS.\n",
108  /* ParserError("substitute_ghost_variable_in_expression",
109  "Functional parameters are not (yet) supported by PIPS\n"); */
111  }
112  MAP(EXPRESSION, e, {
114  }, reference_indices(ref));
115  break;
116  case is_syntax_range:
117  rng = syntax_range(s);
121  break;
122  case is_syntax_call:
123  c = syntax_call(s);
124  pips_assert("Called entities are not substituted", call_function(c)!= v);
125  MAP(EXPRESSION, e, {
127  }, call_arguments(c));
128  break;
129  default:
130  break;
131  }
132 
133  ifdebug(8) {
134  pips_debug(8, "End for expression: ");
135  print_expression(expr);
136  }
137 }
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
void substitute_ghost_variable_in_expression(expression expr, entity v, entity f)
Definition: procedure.c:75
#define syntax_tag(x)
Definition: ri.h:2727
#define reference_undefined
Definition: ri.h:2302
#define range_upper(x)
Definition: ri.h:2290
#define range_undefined
Definition: ri.h:2263
@ is_syntax_range
Definition: ri.h:2692
@ is_syntax_call
Definition: ri.h:2693
@ is_syntax_reference
Definition: ri.h:2691
#define range_increment(x)
Definition: ri.h:2292
#define range_lower(x)
Definition: ri.h:2288
#define call_undefined
Definition: ri.h:685

References call_arguments, call_function, call_undefined, entity_name, EXPRESSION, expression_syntax, f(), ifdebug, is_syntax_call, is_syntax_range, is_syntax_reference, MAP, module_local_name(), pips_assert, pips_debug, pips_user_warning, print_expression(), range_increment, range_lower, range_undefined, range_upper, ref, reference_indices, reference_undefined, reference_variable, syntax_call, syntax_range, syntax_reference, and syntax_tag.

Referenced by substitute_ghost_variable_in_statement().

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

◆ substitute_ghost_variable_in_statement()

void substitute_ghost_variable_in_statement ( statement  stmt,
entity  v,
entity  f 
)

It is assumed that v and f are defined entities and that v is of type variable and f of type functional.

gen_recurse() is not used to control the context better

unstructured u = unstructured_undefined;

Local variables should also be checked

Local variables should also be checked

nothing to do

Parameters
stmttmt

Definition at line 139 of file procedure.c.

143 {
144  /* It is assumed that v and f are defined entities and that v is of
145  type variable and f of type functional. */
146 
147  /* gen_recurse() is not used to control the context better */
148 
151  loop l = loop_undefined;
153  test t = test_undefined;
154  call c = call_undefined;
155  /* unstructured u = unstructured_undefined; */
156 
157  pips_assert("Labels are not substituted", sl!= v);
158 
159  switch(instruction_tag(i)) {
161  MAP(STATEMENT, s, {
163  }, instruction_block(i));
164  break;
165  case is_instruction_loop:
166  l = instruction_loop(i);
167  pips_assert("Loop indices are not substituted", loop_index(l)!= v);
168  pips_assert("Loop labels are not substituted", loop_label(l)!= v);
173  /* Local variables should also be checked */
174  break;
176  w = instruction_whileloop(i);
177  pips_assert("WHILE loop labels are not substituted", whileloop_label(w)!= v);
180  /* Local variables should also be checked */
181  break;
182  case is_instruction_test:
183  t = instruction_test(i);
187  break;
188  case is_instruction_goto:
189  /* nothing to do */
190  break;
191  case is_instruction_call:
192  c = instruction_call(i);
193  pips_assert("Called entities are not substituted", call_function(c)!= v);
194  MAP(EXPRESSION, e, {
196  }, call_arguments(c));
197  break;
199  pips_assert("The parser should not have to know about unstructured\n", false);
200  break;
201  default:
202  FatalError("substitute_ghost_variable_in_statement", "Unexpected instruction tag");
203  }
204 }
#define loop_body(x)
Definition: ri.h:1644
#define loop_undefined
Definition: ri.h:1612
#define test_undefined
Definition: ri.h:2808
#define instruction_loop(x)
Definition: ri.h:1520
#define test_false(x)
Definition: ri.h:2837
@ is_instruction_whileloop
Definition: ri.h:1472
@ is_instruction_test
Definition: ri.h:1470
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_sequence
Definition: ri.h:1469
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define whileloop_label(x)
Definition: ri.h:3164
#define test_true(x)
Definition: ri.h:2835
#define loop_label(x)
Definition: ri.h:1646
#define test_condition(x)
Definition: ri.h:2833
#define instruction_whileloop(x)
Definition: ri.h:1523
#define whileloop_body(x)
Definition: ri.h:3162
#define instruction_call(x)
Definition: ri.h:1529
#define loop_range(x)
Definition: ri.h:1642
#define instruction_test(x)
Definition: ri.h:1517
#define whileloop_condition(x)
Definition: ri.h:3160
#define whileloop_undefined
Definition: ri.h:3134
#define loop_index(x)
Definition: ri.h:1640

References call_arguments, call_function, call_undefined, EXPRESSION, f(), FatalError, instruction_block, instruction_call, instruction_loop, instruction_tag, instruction_test, instruction_whileloop, is_instruction_call, is_instruction_goto, is_instruction_loop, is_instruction_sequence, is_instruction_test, is_instruction_unstructured, is_instruction_whileloop, loop_body, loop_index, loop_label, loop_range, loop_undefined, MAP, pips_assert, range_increment, range_lower, range_upper, STATEMENT, statement_instruction, statement_label, substitute_ghost_variable_in_expression(), test_condition, test_false, test_true, test_undefined, whileloop_body, whileloop_condition, whileloop_label, and whileloop_undefined.

Referenced by remove_ghost_variable_entities().

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

◆ TranslateEntryFormals()

static list TranslateEntryFormals ( entity  e,
list  lfp 
)
static

list of formal parameters wrongly declared in current module

list of effective formal parameters lefp for entry e

the storage is not recoverable

Parameters
lfpentry e

Definition at line 1539 of file procedure.c.

1542 {
1543  list lefp = NIL; /* list of effective formal parameters lefp for entry e */
1544 
1545  ifdebug(1) {
1546  pips_debug(1, "Begin with lfp = ");
1547  dump_arguments(lfp);
1548  }
1549 
1550  MAP(ENTITY, fp, {
1552  entity_type(efp) = copy_type(entity_type(fp));
1553  /* the storage is not recoverable */
1555  lefp = gen_nconc(lefp, CONS(ENTITY, efp, NIL));
1556  }, lfp);
1557 
1558  ifdebug(1) {
1559  pips_debug(1, "\nEnd with lefp = ");
1560  dump_arguments(lefp);
1561  }
1562 
1563  return lefp;
1564 }
value copy_value(value p)
VALUE.
Definition: ri.c:2784

References CONS, copy_type(), copy_value(), dump_arguments(), ENTITY, entity_initial, entity_local_name(), entity_type, FindOrCreateEntity(), gen_nconc(), ifdebug, MAP, module_local_name(), NIL, and pips_debug.

Referenced by MakeEntry().

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

◆ TypeFunctionalEntity()

void TypeFunctionalEntity ( entity  fe,
type  r 
)

this is wrong, because we do not know if we are handling an EXTERNAL declaration, in which case the result type is type_undefined, or a function call appearing somewhere, in which case the ImplicitType should be used; maybe the unknown type should be used?

a bug is detected here: MakeExternalFunction, as its name implies, always makes a FUNCTION, even when the symbol appears in an EXTERNAL statement; the result type is infered from ImplicitType() - see just above -; let's use implicit_type_p() again, whereas the unknown type should have been used

ignore r

someone used a subroutine as a function. this happens in hpfc for declaring "pure" routines. thus I make this case being ignored. warning? FC.

memory leak of tr

This may be an undeclared formal functional argument, initially assumed to be a variable. Since it is not declared as an array but appears with arguments, it must be a functional entity.

I do not know how to get the argument types. Let's hope it's performed later...

Parameters
fee

Definition at line 2257 of file procedure.c.

2259 {
2260  type tfe = entity_type(fe);
2261 
2262  if(tfe == type_undefined) {
2263  /* this is wrong, because we do not know if we are handling
2264  an EXTERNAL declaration, in which case the result type
2265  is type_undefined, or a function call appearing somewhere,
2266  in which case the ImplicitType should be used;
2267  maybe the unknown type should be used? */
2270  (r == type_undefined) ?
2271  ImplicitType(fe) :
2272  r));
2273  }
2274  else if (type_functional_p(tfe))
2275  {
2277  if(r != type_undefined && !type_equal_p(tr, r)) {
2278 
2279  /* a bug is detected here: MakeExternalFunction, as its name
2280  implies, always makes a FUNCTION, even when the symbol
2281  appears in an EXTERNAL statement; the result type is
2282  infered from ImplicitType() - see just above -;
2283  let's use implicit_type_p() again, whereas the unknown type
2284  should have been used
2285  */
2286  if(intrinsic_entity_p(fe)) {
2287  /* ignore r */
2288  } else if (type_void_p(tr)) {
2289  /* someone used a subroutine as a function.
2290  * this happens in hpfc for declaring "pure" routines.
2291  * thus I make this case being ignored. warning? FC.
2292  */
2293  } else if (implicit_type_p(fe) || overloaded_type_p(tr)) {
2294  /* memory leak of tr */
2296  } else {
2297  user_warning("TypeFunctionalEntity",
2298  "Type redefinition of result for function %s\n",
2299  entity_name(fe));
2300  if(type_variable_p(tr)) {
2301  user_warning("TypeFunctionalEntity",
2302  "Currently declared result is %s\n",
2304  }
2305  if(type_variable_p(r)) {
2306  user_warning("TypeFunctionalEntity",
2307  "Redeclared result is %s\n",
2309  }
2310  ParserError("TypeFunctionalEntity",
2311  "Functional type redefinition.\n");
2312  }
2313  }
2314  } else if (type_variable_p(tfe)) {
2315  /* This may be an undeclared formal functional argument, initially
2316  assumed to be a variable. Since it is not declared as an array
2317  but appears with arguments, it must be a functional entity. */
2318  storage sfe = entity_storage(fe);
2319 
2320  if(storage_formal_p(sfe)) {
2321  /* I do not know how to get the argument types. Let's hope it's
2322  performed later...*/
2323  free_type(entity_type(fe));
2325  make_functional(NIL, r));
2326  }
2327  else {
2328  pips_internal_error("Fortran does not support global variables");
2329  }
2330  } else {
2331  pips_internal_error("Unexpected type for a global name %s",
2332  entity_name(fe));
2333  }
2334 }
bool implicit_type_p(entity e)
This function checks that entity e has an undefined or an implicit type which can be superseded by an...
Definition: declaration.c:1358
string basic_to_string(basic)
Definition: type.c:87
bool type_equal_p(type, type)
Definition: type.c:547
bool overloaded_type_p(type)
Returns true if t is a variable type with a basic overloaded.
Definition: type.c:2666

References basic_to_string(), entity_name, entity_storage, entity_type, free_type(), functional_result, implicit_type_p(), ImplicitType(), intrinsic_entity_p(), is_type_functional, make_functional(), make_type(), NIL, overloaded_type_p(), ParserError(), pips_internal_error, storage_formal_p, type_equal_p(), type_functional, type_functional_p, type_undefined, type_variable, type_variable_p, type_void_p, user_warning, and variable_basic.

Referenced by MakeEntry(), and MakeExternalFunction().

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

◆ update_called_modules()

void update_called_modules ( entity  e)

Self recursive calls are not allowed

do not count intrinsics; user function should not be named like intrinsics

FI, 20/01/92: maybe, initializations of global entities should be more precise (storage, initial value, etc...); for the time being, I choose to ignore the potential problems with other executions of the parser and the linker

pips_internal_error("unexpected case");

Definition at line 308 of file procedure.c.

310 {
311  bool already_here = false;
312  const char* n = entity_local_name(e);
313  string nom;
315 
316  /* Self recursive calls are not allowed */
317  if(e==cm) {
318  pips_user_warning("Recursive call from %s to %s\n",
320  ParserError("update_called_modules",
321  "Recursive call are not supported\n");
322  }
323 
324  /* do not count intrinsics; user function should not be named
325  like intrinsics */
328  if(entity_initial(e) == value_undefined) {
329  /* FI, 20/01/92: maybe, initializations of global entities
330  should be more precise (storage, initial value, etc...);
331  for the time being, I choose to ignore the potential
332  problems with other executions of the parser and the linker */
333  /* pips_internal_error("unexpected case"); */
334  }
335  else if(value_intrinsic_p(entity_initial(e)))
336  return;
337  }
338 
339  MAPL(ps, {
340  if (strcmp(n, STRING(CAR(ps))) == 0) {
341  already_here = true;
342  break;
343  }
344  }, called_modules);
345 
346  if (! already_here) {
347  pips_debug(1, "adding %s\n", n);
349  }
350 }

References called_modules, CAR, concatenate(), CONS, entity_domain, entity_initial, entity_local_name(), entity_undefined, gen_find_tabulated(), get_current_module_entity(), MAPL, MODULE_SEP_STRING, ParserError(), pips_debug, pips_user_warning, strdup(), STRING, TOP_LEVEL_MODULE_NAME, value_intrinsic_p, and value_undefined.

Referenced by make_get_rc_statement(), MakeAtom(), MakeCallInst(), and set_rc_function().

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

◆ UpdateFormalStorages()

void UpdateFormalStorages ( entity  m,
list  lfp 
)

this function check and set if necessary the storage of formal parameters in lfp.

formal parameter chunk

formal parameter offset

Oupss... the associated area should be cleaned up... but it should ony occur in EndOfProcedure() when all implictly declared variables have been encountered...

Parameters
lfpfp

Definition at line 2522 of file procedure.c.

2525 {
2526  list fpc; /* formal parameter chunk */
2527  int fpo; /* formal parameter offset */
2528 
2529  for (fpc = lfp, fpo = 1; !ENDP(fpc); POP(fpc), fpo += 1) {
2530  entity fp = ENTITY(CAR(fpc));
2531  storage fps = entity_storage(fp);
2532 
2533  pips_assert("Formal parameter fp must be in scope of module m",
2535 
2536  if(storage_undefined_p(fps)) {
2538  make_formal(m, fpo));
2539  }
2540  else if(storage_ram_p(fps)){
2541  /* Oupss... the associated area should be cleaned up... but
2542  * it should ony occur in EndOfProcedure() when all implictly
2543  * declared variables have been encountered...
2544  */
2545  free_storage(fps);
2547  make_formal(m, fpo));
2548  }
2549  else if(storage_formal_p(fps)){
2550  pips_assert("Consistent Offset",
2551  fpo==formal_offset(storage_formal(fps)));
2552  }
2553  else {
2554  pips_internal_error("Unexpected storage for entity %s",
2555  entity_name(fp));
2556  }
2557  }
2558 }
#define formal_offset(x)
Definition: ri.h:1408
#define storage_formal(x)
Definition: ri.h:2524

References CAR, ENDP, ENTITY, entity_module_name(), entity_name, entity_storage, formal_offset, free_storage(), is_storage_formal, local_name_to_top_level_entity(), make_formal(), make_storage(), pips_assert, pips_internal_error, POP, storage_formal, storage_formal_p, storage_ram_p, and storage_undefined_p.

Referenced by MakeEntry().

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

◆ UpdateFunctionalType()

void UpdateFunctionalType ( entity  f,
list  l 
)

This function analyzes the CurrentFunction formal parameter list to determine the CurrentFunction functional type.

l is this list.

It is called by EndOfProcedure().

FI: I do not understand this assert... at least now that functions may be typed at call sites. I do not understand why this assert has not made more damage. Only OVL in APSI (Spec-cfp95) generates a core dump. To be studied more!

This assert is guaranteed by MakeCurrentFunction() but not by retype_formal_parameters() which is called in case an intrinsic statement is encountered. It is not guaranteed by MakeExternalFunction() which uses the actual parameter list to estimate a functional type

Definition at line 1131 of file procedure.c.

1134 {
1135  cons *pc;
1136  parameter p;
1137  functional ft;
1138  entity CurrentFunction = f;
1139  type t = entity_type(CurrentFunction);
1140 
1141  ifdebug(8) {
1142  pips_debug(8, "Begin for %s with type ",
1143  module_local_name(CurrentFunction));
1144  fprint_functional(stderr, type_functional(t));
1145  (void) fprintf(stderr, "\n");
1146  }
1147 
1148  pips_assert("A module type should be functional", type_functional_p(t));
1149 
1150  ft = type_functional(t);
1151 
1152  /* FI: I do not understand this assert... at least now that
1153  * functions may be typed at call sites. I do not understand why this
1154  * assert has not made more damage. Only OVL in APSI (Spec-cfp95)
1155  * generates a core dump. To be studied more!
1156  *
1157  * This assert is guaranteed by MakeCurrentFunction() but not by
1158  * retype_formal_parameters() which is called in case an intrinsic
1159  * statement is encountered. It is not guaranteed by MakeExternalFunction()
1160  * which uses the actual parameter list to estimate a functional type
1161  */
1162  pips_assert("Parameter type list should be empty",
1164 
1165  for (pc = l; pc != NULL; pc = CDR(pc)) {
1166  entity fp = ENTITY(CAR(pc));
1167  type fpt = entity_type(fp);
1168 
1169  if(type_undefined_p(fpt)) {
1170  entity_type(fp) = ImplicitType(fp);
1171  }
1172 
1173  p = make_parameter((entity_type(fp)),
1175  functional_parameters(ft) =
1177  CONS(PARAMETER, p, NIL));
1178  }
1179 
1180  ifdebug(8) {
1181  pips_debug(8, "End for %s with type ",
1182  module_local_name(CurrentFunction));
1183  fprint_functional(stderr, type_functional(t));
1184  (void) fprintf(stderr, "\n");
1185  }
1186 }
dummy make_dummy_identifier(entity _field_)
Definition: ri.c:620
parameter make_parameter(type a1, mode a2, dummy a3)
Definition: ri.c:1495
void fprint_functional(FILE *fd, functional f)
This function is called from c_parse() via ResetCurrentModule() and fprint_environment()
Definition: declarations.c:227
mode MakeModeReference(void)
Definition: type.c:82
#define functional_parameters(x)
Definition: ri.h:1442
#define PARAMETER(x)
PARAMETER.
Definition: ri.h:1788

References CAR, CDR, CONS, ENDP, ENTITY, entity_type, f(), fprint_functional(), fprintf(), functional_parameters, gen_nconc(), ifdebug, ImplicitType(), make_dummy_identifier(), make_parameter(), MakeModeReference(), module_local_name(), NIL, PARAMETER, pips_assert, pips_debug, type_functional, type_functional_p, and type_undefined_p.

Referenced by EndOfProcedure(), gfc2pips_namespace(), gfc2pips_parameters(), and MakeEntry().

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

Variable Documentation

◆ called_modules

list called_modules = list_undefined
static

list of called subroutines or functions

Definition at line 57 of file procedure.c.

Referenced by BeginingOfProcedure(), build_real_resources(), callgraph(), EndOfProcedure(), remove_from_called_modules(), and update_called_modules().

◆ effective_formal_parameters

list effective_formal_parameters = NIL
static

◆ entry_entities

list entry_entities = NIL
static

◆ entry_labels

list entry_labels = NIL
static

Processing of entries: when an ENTRY statement is encountered, it is replaced by a labelled CONTINUE and the entry is declared as function or a subroutine, depending on its type.

The label and the module entity which are created are stored in two static lists, entry_labels and entry_entities, for later processing. When the current module has been fully parsed, the two entry lists are scanned together. The current module code is duplicated for each entry, a GOTO the proper entry label is added, the code is controlized to get rid of the unwanted pieces of code, and:

  • either all references are translated into the entry reference. The entry declarations are then initialized.
  • or the controlized code is prettyprinted as SOURCE_FILE and parser again to avoid the translation issue.

The second approach was selected. The current .f file is overwritten when the parser is called for the code of an entry.

Further problems are created by entries in fsplit which creates a .f_initial file for each entry and in the parser which may not produce the expected PARSED_CODE when it is called for an ENTRY. A recursive call to the parser is executed to parse the .f file just produced by the first call. This scheme was designed to make entries unvisible from pipsmake.

Definition at line 1453 of file procedure.c.

Referenced by AbortEntries(), AddEntryLabel(), EmptyEntryListsP(), ProcessEntries(), and ResetEntries().

◆ entry_targets

list entry_targets = NIL
static

Definition at line 1454 of file procedure.c.

Referenced by AbortEntries(), AddEntryTarget(), ProcessEntries(), and ResetEntries().

◆ function_body

statement function_body = statement_undefined
static

statement of current function

Definition at line 60 of file procedure.c.

Referenced by EndOfProcedure(), MakeCurrentFunction(), and remove_ghost_variable_entities().

◆ ghost_variable_entities

list ghost_variable_entities = list_undefined
static

list of potential local or top-level variables that turned out to be useless.

Definition at line 67 of file procedure.c.

Referenced by AbortOfProcedure(), add_ghost_variable_entity(), ghost_variable_entity_p(), init_ghost_variable_entities(), reify_ghost_variable_entity(), and remove_ghost_variable_entities().

◆ implicit_do_index_set

list implicit_do_index_set = list_undefined
static