PIPS
|
#include <stdio.h>
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "ri-util.h"
#include "workspace-util.h"
#include "parser_private.h"
#include "properties.h"
#include "misc.h"
#include "syntax.h"
Go to the source code of this file.
Macros | |
#define | EQUIADD 0 |
lint More... | |
#define | EQUIMERGE 1 |
Functions | |
void | ResetChains () |
undefine chains between two successives calls to parser More... | |
void | SetChains () |
initialize chains before each call to the parser More... | |
atom | MakeEquivAtom (syntax s) |
this function creates an atom of an equivalence chain. More... | |
void | StoreEquivChain (chain c) |
This function is called when an equivalence chain has been completely parsed. More... | |
void | ComputeEquivalences () |
This function merges all the equivalence chains to take into account equivalences due to transitivity. More... | |
int | AddOrMergeChain (chain ct) |
this function adds a chain ct to the set of equivalences. More... | |
int | ChainIntersection (cons *opc1, cons *opc2) |
this function returns true if the there is a variable that occurs in both atom lists. More... | |
cons * | MergeTwoChains (cons *opc1, cons *opc2) |
this function merges two equivalence chains whose intersection is not empty, ie. More... | |
void | PrintChains (equivalences e) |
two debugging functions, just in case ... More... | |
void | PrintChain (chain c) |
bool | entity_in_equivalence_chains_p (entity e) |
bool | entity_in_equivalence_chain_p (entity e, chain c) |
void | ComputeAddresses () |
This function computes an address for every variable. More... | |
void | SaveChains () |
Initialize the shared fields of aliased variables. More... | |
Variables | |
char | vcid_syntax_equivalence [] = "$Id: equivalence.c 23065 2016-03-02 09:05:50Z coelho $" |
Support and resolve equivalence chains. More... | |
static equivalences | TempoEquivSet = equivalences_undefined |
external variables used by functions from equivalence.c More... | |
static equivalences | FinalEquivSet = equivalences_undefined |
#define EQUIADD 0 |
lint
equivalence.c: contains EQUIVALENCE related routines
Definition at line 54 of file equivalence.c.
#define EQUIMERGE 1 |
Definition at line 55 of file equivalence.c.
this function adds a chain ct to the set of equivalences.
if the intersection with all other chains is empty, ct is just added to the set. Otherwise ct is merged with the chain that intersects ct.
ct | t |
Definition at line 269 of file equivalence.c.
References CAR, CDR, CHAIN, chain_atoms, ChainIntersection(), CONS, EQUIADD, EQUIMERGE, equivalences_chains, FinalEquivSet, make_chain(), MergeTwoChains(), and NIL.
Referenced by ComputeEquivalences().
this function returns true if the there is a variable that occurs in both atom lists.
opc1 | pc1 |
opc2 | pc2 |
Definition at line 302 of file equivalence.c.
References ATOM, atom_equivar, CAR, CDR, gen_eq(), and NIL.
Referenced by AddOrMergeChain().
void ComputeAddresses | ( | void | ) |
This function computes an address for every variable.
Three different cases are adressed: variables in user-declared commons, static variables and dynamic variables.
Variables may have:
All variables explictly declared in a common have a storage fully defined within this common (see update_common_layout() which must have been called before entering ComputeAddresses()). If such a variable occurs in an equivalence chain, all other variables of this chain will have an address in this common. The exact address depends on the offset stored in the atom.
The variables allocated in the static and dynamic areas are handled differently from variables explicitly declared in a common because the programmer does not have a direct control over the offset as within a common declaration. An arbitrary allocation is performed. The same kind of processing is done for chains containing a static variable or only dynamic variables (i.e. each variable in the chain has an undefined storage).
Static variables obviously have a partially defined storage since they are recognized as static.
Each equivalence chain should be either attached to a user-declared common or to the static area or to the dynamic area of the current module.
Static and dynamic chains are processed in a similar way. The size of each chain is computed and the space for the chain is allocated in the corresponding area. As for user-declared commons (but with no good reason?) only one representant of each chain is added to the layouts of the area.
When the processing of equivalenced variables is completed, non-equivalenced static or dynamic (i.e. variables with undefined storage) variables are allocated.
Finally equivalenced variables are appended to the layouts of the static and dynamic areas. This makes update_common_layout() unapplicable.
As a result, variables declared in the static and dynamic area are not ordered by increasing offsets.
the default section for variables with no address is the dynamic area.
Try to locate the area for the current equivalence chain. Only one variable should have a well-defined storage. Or no variables have one because the equivalence chain is located in the dynamic area.
Compute the total size of the chain. This only should be used for the static and dynamic areas
FI: I do not understand why this assignment is not better guarded. Maybe, because lc's later use is guarded.
A variable may be located in a static area because of a SAVE (?) or a DATA statement and be equivalenced with a variable in a common.
Same as above but in a different order
Let's hope this is due to a DATA and not to a SAVE
Compute the offset and set the storage information for each variable in the equivalence chain that has no storage yet.
check that the offset is positive
Static aliases cannot be added right away because implicitly declared static variables still have to be added whereas aliased variables are assumed to be put behind in the layout list. Except the first one.
Well, I'm not so sure!
Add e in sc'layout and check that sc's size does not have to be increased as for: COMMON /FOO/X REAL Y(100) EQUIVALENCE (X,Y)
Dynamic aliases cannot be added right away because implicitly declared dynamic variables still have to be added whereas aliased variables are assumed to be put behind in the layout list. Except the first one.
If sc really is a common, i.e. neither the dynamic nor the static area, check its size
Varying size arrays must be stack allocated. This is an implicit extension that is not compatible with EQUIVALENCE
This test will fail for stack allocatable varying length character strings because of function SizeOfElements() which cannot indicate failure. Let's wait for the problem...
Try to reallocate in stack area
Formal parameters can have varying sizes
Allocatable arrays can have varying sizes
Could be declared explicitly or implicitly STATIC or be EQUIVALENCEd with such a variable. It could be declared in a COMMON.
The array size is known at compile time. Allocate in synamic area.
All declared variables are scanned and stored in the dynamic area if their storage is still undefined or in the static area if their offsets are still unkown.
This should be the case for all non-aliased static variables and most dynamic variables.
area da = type_area(entity_type(DynamicArea));
area_layout(da) = gen_nconc(area_layout(da), CONS(ENTITY, e, NIL));
area sa = type_area(entity_type(StaticArea));
area_layout(sa) = gen_nconc(area_layout(sa), CONS(ENTITY, e, NIL));
Must be stack area
Add aliased dynamic variables
neither gen_concatenate() nor gen_append() are OK
side effect on area_layout
Add aliased static variables
neither gen_concatenate() nor gen_append() are OK
side effect on area_layout
The sizes of the static and dynamic areas are now known
Definition at line 503 of file equivalence.c.
References area_layout, area_size, arguments_add_entity(), ATOM, atom_equioff, atom_equivar, CAR, CDR, CHAIN, chain_atoms, code_declarations, common_to_size(), CONS, current_offset_of_area(), DynamicArea, ENDP, ENTITY, entity_is_argument_p(), entity_local_name(), entity_name, entity_storage, entity_type, EntityCode(), equivalences_chains, equivalences_undefined, FatalError, FinalEquivSet, gen_nconc(), get_bool_property(), get_current_module_entity(), HeapArea, ifdebug, is_storage_ram, make_ram(), make_storage(), NIL, ParserError(), pips_assert, pips_debug, pips_internal_error, pips_user_warning, print_arguments(), ram_offset, ram_section, SafeSizeOfArray(), SizeOfArray(), StackArea, StaticArea, storage_formal_p, storage_ram, storage_ram_p, storage_undefined, storage_undefined_p, top_level_entity_p(), type_area, type_variable_p, UNKNOWN_RAM_OFFSET, update_common_to_size(), and user_warning.
Referenced by EndOfProcedure().
void ComputeEquivalences | ( | void | ) |
This function merges all the equivalence chains to take into account equivalences due to transitivity.
It is called at the end of the parsing.
They should be properly initialized by SetChains if (FinalEquivSet == equivalences_undefined) { FinalEquivSet = make_equivalences(NIL); }
Definition at line 215 of file equivalence.c.
References AddOrMergeChain(), CAR, CDR, CHAIN, ENDP, EQUIMERGE, equivalences_chains, FinalEquivSet, free_equivalences(), make_equivalences(), NIL, pips_debug, PrintChains(), and TempoEquivSet.
Referenced by EndOfProcedure().
Definition at line 420 of file equivalence.c.
References ATOM, atom_equivar, CAR, chain_atoms, ENDP, entity_name, pips_debug, and POP.
Referenced by entity_in_equivalence_chains_p().
Apparently, TempoEquivSet stays undefined when there are no equivalences
Definition at line 403 of file equivalence.c.
References CAR, CHAIN, ENDP, entity_in_equivalence_chain_p(), equivalences_chains, equivalences_undefined_p, POP, and TempoEquivSet.
Referenced by remove_ghost_variable_entities().
this function creates an atom of an equivalence chain.
s is a reference to a variable.
reference offset
substring offset
Equivalenced variables cannot be initialized by a DATA statement: false
In case, the entity is not of type variable, reject it.
In case an adjustable array which is not a formal parameter has been encountered, reject it.
what is the offset of this reference ?
Definition at line 89 of file equivalence.c.
References array_with_numerical_bounds_p(), call_arguments, call_function, CAR, CDR, entity_local_name(), entity_storage, entity_type, EXPRESSION, expression_constant_p(), expression_syntax, expression_to_int(), formal_parameter_p(), make_atom(), module_local_name(), OffsetOfReference(), ParserError(), pips_assert, pips_debug, pips_user_warning, reference_undefined, reference_variable, storage_undefined_p, SUBSTRING_FUNCTION_NAME, syntax_call, syntax_call_p, syntax_reference, syntax_reference_p, and type_variable_p.
this function merges two equivalence chains whose intersection is not empty, ie.
one variable occurs in both chains.
opc1 | pc1 |
opc2 | pc2 |
Definition at line 322 of file equivalence.c.
References abs, ATOM, atom_equioff, atom_equivar, CAR, CDR, FatalError, gen_eq(), and NIL.
Referenced by AddOrMergeChain().
void PrintChain | ( | chain | c | ) |
Definition at line 382 of file equivalence.c.
References ATOM, atom_equioff, atom_equivar, CAR, CDR, chain_atoms, entity_name, fprintf(), ifdebug, NIL, and pips_debug.
Referenced by PrintChains().
void PrintChains | ( | equivalences | e | ) |
two debugging functions, just in case ...
Definition at line 364 of file equivalence.c.
References CAR, CDR, CHAIN, ENDP, equivalences_chains, fprintf(), ifdebug, NIL, and PrintChain().
Referenced by ComputeEquivalences().
void ResetChains | ( | void | ) |
undefine chains between two successives calls to parser
Definition at line 65 of file equivalence.c.
References equivalences_undefined, FinalEquivSet, free_equivalences(), and TempoEquivSet.
Referenced by EndOfProcedure(), gfc2pips_namespace(), and ParserError().
void SaveChains | ( | void | ) |
Initialize the shared fields of aliased variables.
shared = CONS(ENTITY, atom_equivar(ATOM(CAR(pa))), shared);
Check conflicting intializations
Definition at line 859 of file equivalence.c.
References ATOM, atom_equivar, CAR, CHAIN, chain_atoms, ENDP, ENTITY, entity_initial, entity_local_name(), entity_name, entity_storage, equivalences_chains, equivalences_undefined, FinalEquivSet, gen_copy_seq(), gen_once(), MAP, MAPL, NIL, ParserError(), pips_assert, pips_debug, pips_user_warning, ram_shared, storage_ram, value_defined_p(), value_unknown_p, and variable_entities_may_conflict_p().
Referenced by EndOfProcedure().
void SetChains | ( | void | ) |
initialize chains before each call to the parser
Definition at line 76 of file equivalence.c.
References equivalences_undefined_p, FinalEquivSet, make_equivalences(), NIL, pips_assert, and TempoEquivSet.
Referenced by MakeCurrentFunction().
void StoreEquivChain | ( | chain | c | ) |
This function is called when an equivalence chain has been completely parsed.
It looks for the atom with the biggest offset, and then substracts this maximum offset from all atoms. The result is that each atom has its offset from the begining of the chain.
Definition at line 176 of file equivalence.c.
References abs, ATOM, atom_equioff, CAR, CDR, CHAIN, chain_atoms, CONS, equivalences_chains, equivalences_undefined_p, NIL, pips_assert, pips_debug, and TempoEquivSet.
|
static |
Definition at line 60 of file equivalence.c.
Referenced by AddOrMergeChain(), ComputeAddresses(), ComputeEquivalences(), ResetChains(), SaveChains(), and SetChains().
|
static |
external variables used by functions from equivalence.c
Definition at line 59 of file equivalence.c.
Referenced by ComputeEquivalences(), entity_in_equivalence_chains_p(), ResetChains(), SetChains(), and StoreEquivChain().
char vcid_syntax_equivalence[] = "$Id: equivalence.c 23065 2016-03-02 09:05:50Z coelho $" |
Support and resolve equivalence chains.
Allocate addresses in commons and in the static area and in the dynamic area. The heap area is left aside.
Definition at line 33 of file equivalence.c.