PIPS
area.c
Go to the documentation of this file.
1 /*
2 
3  $Id: area.c$
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 /* Pot-pourri of utilities for entities of kind "area"
28  *
29  */
30 #include <stdio.h>
31 #include <string.h>
32 
33 #include "genC.h"
34 #include "linear.h"
35 
36 #include "misc.h"
37 #include "ri.h"
38 
39 #include "ri-util.h"
40 
41 /* functions for areas */
42 
43 /* Four areas used to allocate variables which are not stored in a
44  Fortran common. These areas are just like Fortran commons, but the
45  dynamic area is the only non-static area according to Fortran
46  standard. The heap and the stack area are used to deal with Fortran
47  ANSI extensions and C, pointers and allocatable arrays, and
48  adjustable arrays (VLA in C). The dynamic area is stack allocated
49  by most compilers but could be statically allocated since the array
50  sizes are known.
51 
52  Areas are declared for each module. These four global variables are
53  managed by the Fortran and C parsers and used to allocate variables
54  in the current module. Note that the C parser uses more areas at
55  the same time to cope with global variables.
56  */
62 
63 
66 }
67 
69 {
70 #ifndef NDEBUG
72  pips_assert("entity_kind is consistent", result == ( (entity_kind(aire) & ENTITY_DYNAMIC_AREA) == ENTITY_DYNAMIC_AREA));
73 #endif
74  return entity_kind(aire) & ENTITY_DYNAMIC_AREA;
75 }
76 
78 {
79 #ifndef NDEBUG
81  pips_assert("entity_kind is consistent", result == ( (entity_kind(aire) & ENTITY_STATIC_AREA) == ENTITY_STATIC_AREA));
82 #endif
83  return entity_kind(aire) & ENTITY_STATIC_AREA;
84 }
85 
86 bool heap_area_p(entity aire)
87 {
88 #ifndef NDEBUG
90  pips_assert("entity_kind is consistent", result == ( (entity_kind(aire) & ENTITY_HEAP_AREA) == ENTITY_HEAP_AREA));
91 #endif
92  return entity_kind(aire) & ENTITY_HEAP_AREA;
93 }
94 
96 {
97 #ifndef NDEBUG
99  pips_assert("entity_kind is consistent", result == ( (entity_kind(aire) & ENTITY_FORMAL_AREA) == ENTITY_FORMAL_AREA));
100 #endif
101  return entity_kind(aire) & ENTITY_FORMAL_AREA;
102 }
103 
105 {
106 #ifndef NDEBUG
108  pips_assert("entity_kind is consistent", result == ( (entity_kind(aire) & ENTITY_STACK_AREA) == ENTITY_STACK_AREA));
109 #endif
110  return entity_kind(aire) & ENTITY_STACK_AREA;
111 }
112 
114 {
115 #ifndef NDEBUG
117  pips_assert("entity_kind is consistent", result == ( (entity_kind(aire) & ENTITY_POINTER_DUMMY_TARGETS_AREA) == ENTITY_POINTER_DUMMY_TARGETS_AREA));
118 #endif
120 }
121 
122 
123 
124 /* Returns the heap area "a" associated to module "f". Area "a" is always a
125  defined entity.
126 
127  Assumes that f is defined, as well as its heap area.
128 */
130 {
132 
133  pips_assert("The heap area is defined for module f.\n",
134  !entity_undefined_p(a));
135 
136  return a;
137 }
138 
140 {
142 
143  pips_assert("The dynamic area is defined for module f.\n",
144  !entity_undefined_p(a));
145 
146  return a;
147 }
148 
150 {
151  return !type_undefined_p(entity_type(e)) && type_area_p(entity_type(e));//static_area_p(e) || dynamic_area_p(e) || heap_area_p(e) || stack_area_p(e);
152 }
153 
155 {
156  return entity_area_p(e) &&
158 }
159 
160 /*
161  * This function computes the current offset of the area a passed as
162  * argument. The memory footprint of the variable v is also computed
163  * and then added to a's offset. The initial offset is returned to the
164  * calling function. The layout of the area is updated.
165  *
166  * The memory footprint cannot be computed for C and Fortran varying
167  * length arrays (VLA). They are allocated in the StackArea. We could
168  * check here that area a is not the StackArea and/or that a is the
169  * StackArea if the memory footprint of v cannot be statically
170  * computed.
171  *
172  * A similar function, CurrentOffsetOfArea(), is used by the Fortran parser.
173  */
175  entity v /* scalar or array variable */)
176 {
177  int OldOffset;
178  type ta = entity_type(a);
179  area aa = type_area(ta);
180 
181  /* the local areas are StaticArea, DynamicArea, HeapArea, StackArea */
182  OldOffset = area_size(aa);
183  int s;
184  if (!SizeOfArray(v, &s)) {
185  /* Varying Length Arrays (VLA) in C or Fortran must be allocated
186  * in the stack area, where offsets are not computed in the same
187  * way.
188  */
189  pips_internal_error("Ill. arg.: VLA");
190  }
191  else {
192  pips_assert("Offsets are not computed this way in stack areas.\n",
193  !stack_area_p(a));
194  area_size(aa) = OldOffset + s;
195  }
196 
197  area_layout(aa) = gen_nconc(area_layout(aa), CONS(ENTITY, v, NIL));
198  return OldOffset;
199 }
200 
202 {
203  if (!static_area_p(e)) return false;
204  return ENDP(area_layout(type_area(entity_type(e))));
205 }
206 
207 void print_common_layout(FILE * fd, entity c, bool debug_p)
208 {
210  /* list members = area_layout(type_area(entity_type(c))); */
211  /* list members = common_members_of_module(c, mod , true); */
212  /* for debugging only */
213  list members = common_members_of_module(c, mod , false);
214  list equiv_members = NIL;
215 
216  (void) fprintf(fd,"\nLayout for common /%s/ of size %td:\n",
218 
219  if(ENDP(members)) {
220  pips_assert("An empty area has size 0", area_size(type_area(entity_type(c)))==0);
221  (void) fprintf(fd, "\t* empty area *\n\n");
222  }
223  else {
224  if(area_size(type_area(entity_type(c)))==0
225  // The next condition cannot be tested outside of the Fortran parser
226  // && (common_size_map == hash_table_undefined || common_to_size(c)==0)
227  && !heap_area_p(c)
228  && !stack_area_p(c)) {
229  if(debug_p) {
230  pips_user_warning("Non-empty area %s should have a final size greater than 0\n",
231  entity_module_name(c));
232  }
233  else {
234  pips_internal_error("Non-empty area %s should have a size greater than 0",
235  entity_module_name(c));
236  }
237  }
238  /* Look for variables declared in this common by *some* procedures
239  * which declares it. The procedures involved depend on the ordering
240  * of the parser steps by pipsmake and the user. Maybe, the list should
241  * be filtered and restricted to the current module: YES!
242  */
243  FOREACH(ENTITY, m, members)
244  {
245  pips_assert("RAM storage",
247  if(ram_function(storage_ram(entity_storage(m)))==mod) {
248  int s;
249 
250  /* Consistency check between the area layout and the ram section */
252  pips_internal_error("Variable %s declared in area %s but allocated in area %s",
255  }
256 
257  if(!SizeOfArray(m, &s)) {
260  s = -1;
261  }
262  else {
263  pips_user_warning("Varying size of array \"%s\"\n",
264  entity_name(m));
265  // VLA are now supported by PIPS in the stack_area and the dynamic_area
266  pips_internal_error("Fortran standard prohibit varying size array\n");
267  }
268  }
269 
270  (void) fprintf(fd,
271  "\tVariable %s,\toffset = %td,\tsize = %d\n",
272  entity_name(m),
274  s);
275 
276  }
277  }
278  (void) fprintf(fd, "\n");
279 
280  /* Look for variables aliased with a variable in this common */
281  FOREACH(ENTITY, m, members)
282  {
284  equiv_members = arguments_union(equiv_members, equiv);
285  }
286 
287  if(!ENDP(equiv_members)){
288 
289  equiv_members = arguments_difference(equiv_members, members);
290  if(!ENDP(equiv_members)) {
291  sort_list_of_entities(equiv_members);
292 
293  (void) fprintf(fd, "\tVariables aliased to this common:\n");
294 
295  FOREACH(ENTITY, m, equiv_members)
296  {
297  pips_assert("RAM storage",
299  (void) fprintf(fd,
300  "\tVariable %s,\toffset = %td,\tsize = %d\n",
301  entity_name(m),
303  array_size(m));
304  }
305  (void) fprintf(fd, "\n");
306  gen_free_list(equiv_members);
307  }
308  }
309  }
310  gen_free_list(members);
311 }
cons * arguments_union(cons *a1, cons *a2)
cons * arguments_union(cons * a1, cons * a2): returns a = union(a1, a2) where a1 and a2 are lists of ...
Definition: arguments.c:116
cons * arguments_difference(cons *a1, cons *a2)
set difference: a1 - a2 ; similar to set intersection
Definition: arguments.c:233
static int array_size(dim)
ARRAY_SIZE returns the number of elements in the array whose dimension list is DIM.
Definition: genClib.c:155
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define pips_user_warning
Definition: misc-local.h:146
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_internal_error
Definition: misc-local.h:149
#define FORMAL_AREA_LOCAL_NAME
Definition: naming-local.h:76
#define DYNAMIC_AREA_LOCAL_NAME
Definition: naming-local.h:69
#define ALLOCATABLE_AREA_LOCAL_NAME
Definition: naming-local.h:73
#define STACK_AREA_LOCAL_NAME
Definition: naming-local.h:72
#define POINTER_DUMMY_TARGETS_AREA_LOCAL_NAME
Definition: naming-local.h:77
#define STATIC_AREA_LOCAL_NAME
Definition: naming-local.h:70
#define HEAP_AREA_LOCAL_NAME
Definition: naming-local.h:71
#define same_string_p(s1, s2)
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
@ ENTITY_POINTER_DUMMY_TARGETS_AREA
@ ENTITY_STATIC_AREA
@ ENTITY_FORMAL_AREA
@ ENTITY_DYNAMIC_AREA
@ ENTITY_STACK_AREA
@ ENTITY_HEAP_AREA
bool dynamic_area_p(entity aire)
Definition: area.c:68
void print_common_layout(FILE *fd, entity c, bool debug_p)
Definition: area.c:207
entity DynamicArea
Pot-pourri of utilities for entities of kind "area".
Definition: area.c:57
bool pointer_dummy_targets_area_p(entity aire)
Definition: area.c:113
entity HeapArea
Definition: area.c:59
bool entity_area_p(entity e)
Definition: area.c:149
bool stack_area_p(entity aire)
Definition: area.c:104
bool heap_area_p(entity aire)
Definition: area.c:86
entity module_to_dynamic_area(entity f)
Definition: area.c:139
int current_offset_of_area(entity a, entity v)
Definition: area.c:174
entity StaticArea
Definition: area.c:58
bool empty_static_area_p(entity e)
Definition: area.c:201
entity StackArea
Definition: area.c:60
bool formal_area_p(entity aire)
Definition: area.c:95
entity module_to_heap_area(entity f)
Returns the heap area "a" associated to module "f".
Definition: area.c:129
entity AllocatableArea
Definition: area.c:61
bool allocatable_area_p(entity aire)
Definition: area.c:64
bool static_area_p(entity aire)
Definition: area.c:77
bool entity_special_area_p(entity e)
Definition: area.c:154
entity FindEntity(const char *package, const char *name)
Retrieve an entity from its package/module name and its local name.
Definition: entity.c:1503
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
void sort_list_of_entities(list l)
sorted in place.
Definition: entity.c:1358
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
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
bool SizeOfArray(entity, int *)
This function computes the total size of a variable in bytes, ie.
Definition: size.c:87
#define area_size(x)
Definition: ri.h:544
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define entity_storage(x)
Definition: ri.h:2794
#define storage_ram_p(x)
Definition: ri.h:2519
#define ram_section(x)
Definition: ri.h:2249
#define type_undefined_p(x)
Definition: ri.h:2884
#define entity_undefined_p(x)
Definition: ri.h:2762
#define entity_undefined
Definition: ri.h:2761
#define entity_name(x)
Definition: ri.h:2790
#define area_layout(x)
Definition: ri.h:546
#define type_area(x)
Definition: ri.h:2946
#define storage_ram(x)
Definition: ri.h:2521
#define ram_function(x)
Definition: ri.h:2247
#define type_area_p(x)
Definition: ri.h:2944
#define entity_kind(x)
Definition: ri.h:2798
#define entity_type(x)
Definition: ri.h:2792
#define ram_shared(x)
Definition: ri.h:2253
#define ram_offset(x)
Definition: ri.h:2251
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
The structure used to build lists in NewGen.
Definition: newgen_list.h:41