* Make-lang.in (GFORTRAN_TARGET_INSTALL_NAME): Define.
[official-gcc.git] / gcc / fortran / trans-common.c
blobebd7f52627ec0cd464c8eb431b7682c95a3ab0f6
1 /* Common block and equivalence list handling
2 Copyright (C) 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
3 Contributed by Canqun Yang <canqun@nudt.edu.cn>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
22 /* The core algorithm is based on Andy Vaught's g95 tree. Also the
23 way to build UNION_TYPE is borrowed from Richard Henderson.
25 Transform common blocks. An integral part of this is processing
26 equivalence variables. Equivalenced variables that are not in a
27 common block end up in a private block of their own.
29 Each common block or local equivalence list is declared as a union.
30 Variables within the block are represented as a field within the
31 block with the proper offset.
33 So if two variables are equivalenced, they just point to a common
34 area in memory.
36 Mathematically, laying out an equivalence block is equivalent to
37 solving a linear system of equations. The matrix is usually a
38 sparse matrix in which each row contains all zero elements except
39 for a +1 and a -1, a sort of a generalized Vandermonde matrix. The
40 matrix is usually block diagonal. The system can be
41 overdetermined, underdetermined or have a unique solution. If the
42 system is inconsistent, the program is not standard conforming.
43 The solution vector is integral, since all of the pivots are +1 or -1.
45 How we lay out an equivalence block is a little less complicated.
46 In an equivalence list with n elements, there are n-1 conditions to
47 be satisfied. The conditions partition the variables into what we
48 will call segments. If A and B are equivalenced then A and B are
49 in the same segment. If B and C are equivalenced as well, then A,
50 B and C are in a segment and so on. Each segment is a block of
51 memory that has one or more variables equivalenced in some way. A
52 common block is made up of a series of segments that are joined one
53 after the other. In the linear system, a segment is a block
54 diagonal.
56 To lay out a segment we first start with some variable and
57 determine its length. The first variable is assumed to start at
58 offset one and extends to however long it is. We then traverse the
59 list of equivalences to find an unused condition that involves at
60 least one of the variables currently in the segment.
62 Each equivalence condition amounts to the condition B+b=C+c where B
63 and C are the offsets of the B and C variables, and b and c are
64 constants which are nonzero for array elements, substrings or
65 structure components. So for
67 EQUIVALENCE(B(2), C(3))
68 we have
69 B + 2*size of B's elements = C + 3*size of C's elements.
71 If B and C are known we check to see if the condition already
72 holds. If B is known we can solve for C. Since we know the length
73 of C, we can see if the minimum and maximum extents of the segment
74 are affected. Eventually, we make a full pass through the
75 equivalence list without finding any new conditions and the segment
76 is fully specified.
78 At this point, the segment is added to the current common block.
79 Since we know the minimum extent of the segment, everything in the
80 segment is translated to its position in the common block. The
81 usual case here is that there are no equivalence statements and the
82 common block is series of segments with one variable each, which is
83 a diagonal matrix in the matrix formulation.
85 Each segment is described by a chain of segment_info structures. Each
86 segment_info structure describes the extents of a single varible within
87 the segment. This list is maintained in the order the elements are
88 positioned withing the segment. If two elements have the same starting
89 offset the smaller will come first. If they also have the same size their
90 ordering is undefined.
92 Once all common blocks have been created, the list of equivalences
93 is examined for still-unused equivalence conditions. We create a
94 block for each merged equivalence list. */
96 #include "config.h"
97 #include "system.h"
98 #include "coretypes.h"
99 #include "tree.h"
100 #include "toplev.h"
101 #include "tm.h"
102 #include "gfortran.h"
103 #include "trans.h"
104 #include "trans-types.h"
105 #include "trans-const.h"
108 /* Holds a single variable in an equivalence set. */
109 typedef struct segment_info
111 gfc_symbol *sym;
112 HOST_WIDE_INT offset;
113 HOST_WIDE_INT length;
114 /* This will contain the field type until the field is created. */
115 tree field;
116 struct segment_info *next;
117 } segment_info;
119 static segment_info * current_segment;
120 static gfc_namespace *gfc_common_ns = NULL;
122 /* Make a segment_info based on a symbol. */
124 static segment_info *
125 get_segment_info (gfc_symbol * sym, HOST_WIDE_INT offset)
127 segment_info *s;
129 /* Make sure we've got the character length. */
130 if (sym->ts.type == BT_CHARACTER)
131 gfc_conv_const_charlen (sym->ts.cl);
133 /* Create the segment_info and fill it in. */
134 s = (segment_info *) gfc_getmem (sizeof (segment_info));
135 s->sym = sym;
136 /* We will use this type when building the segment aggregate type. */
137 s->field = gfc_sym_type (sym);
138 s->length = int_size_in_bytes (s->field);
139 s->offset = offset;
141 return s;
144 /* Add combine segment V and segment LIST. */
146 static segment_info *
147 add_segments (segment_info *list, segment_info *v)
149 segment_info *s;
150 segment_info *p;
151 segment_info *next;
153 p = NULL;
154 s = list;
156 while (v)
158 /* Find the location of the new element. */
159 while (s)
161 if (v->offset < s->offset)
162 break;
163 if (v->offset == s->offset
164 && v->length <= s->length)
165 break;
167 p = s;
168 s = s->next;
171 /* Insert the new element in between p and s. */
172 next = v->next;
173 v->next = s;
174 if (p == NULL)
175 list = v;
176 else
177 p->next = v;
179 p = v;
180 v = next;
183 return list;
186 /* Construct mangled common block name from symbol name. */
188 static tree
189 gfc_sym_mangled_common_id (const char *name)
191 int has_underscore;
192 char mangled_name[GFC_MAX_MANGLED_SYMBOL_LEN + 1];
194 if (strcmp (name, BLANK_COMMON_NAME) == 0)
195 return get_identifier (name);
197 if (gfc_option.flag_underscoring)
199 has_underscore = strchr (name, '_') != 0;
200 if (gfc_option.flag_second_underscore && has_underscore)
201 snprintf (mangled_name, sizeof mangled_name, "%s__", name);
202 else
203 snprintf (mangled_name, sizeof mangled_name, "%s_", name);
205 return get_identifier (mangled_name);
207 else
208 return get_identifier (name);
212 /* Build a field declaration for a common variable or a local equivalence
213 object. */
215 static void
216 build_field (segment_info *h, tree union_type, record_layout_info rli)
218 tree field;
219 tree name;
220 HOST_WIDE_INT offset = h->offset;
221 unsigned HOST_WIDE_INT desired_align, known_align;
223 name = get_identifier (h->sym->name);
224 field = build_decl (FIELD_DECL, name, h->field);
225 gfc_set_decl_location (field, &h->sym->declared_at);
226 known_align = (offset & -offset) * BITS_PER_UNIT;
227 if (known_align == 0 || known_align > BIGGEST_ALIGNMENT)
228 known_align = BIGGEST_ALIGNMENT;
230 desired_align = update_alignment_for_field (rli, field, known_align);
231 if (desired_align > known_align)
232 DECL_PACKED (field) = 1;
234 DECL_FIELD_CONTEXT (field) = union_type;
235 DECL_FIELD_OFFSET (field) = size_int (offset);
236 DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
237 SET_DECL_OFFSET_ALIGN (field, known_align);
239 rli->offset = size_binop (MAX_EXPR, rli->offset,
240 size_binop (PLUS_EXPR,
241 DECL_FIELD_OFFSET (field),
242 DECL_SIZE_UNIT (field)));
243 /* If this field is assigned to a label, we create another two variables.
244 One will hold the address of target label or format label. The other will
245 hold the length of format label string. */
246 if (h->sym->attr.assign)
248 tree len;
249 tree addr;
251 gfc_allocate_lang_decl (field);
252 GFC_DECL_ASSIGN (field) = 1;
253 len = gfc_create_var_np (gfc_charlen_type_node,h->sym->name);
254 addr = gfc_create_var_np (pvoid_type_node, h->sym->name);
255 TREE_STATIC (len) = 1;
256 TREE_STATIC (addr) = 1;
257 DECL_INITIAL (len) = build_int_cst (NULL_TREE, -2);
258 gfc_set_decl_location (len, &h->sym->declared_at);
259 gfc_set_decl_location (addr, &h->sym->declared_at);
260 GFC_DECL_STRING_LEN (field) = pushdecl_top_level (len);
261 GFC_DECL_ASSIGN_ADDR (field) = pushdecl_top_level (addr);
264 h->field = field;
268 /* Get storage for local equivalence. */
270 static tree
271 build_equiv_decl (tree union_type, bool is_init, bool is_saved)
273 tree decl;
274 char name[15];
275 static int serial = 0;
277 if (is_init)
279 decl = gfc_create_var (union_type, "equiv");
280 TREE_STATIC (decl) = 1;
281 return decl;
284 snprintf (name, sizeof (name), "equiv.%d", serial++);
285 decl = build_decl (VAR_DECL, get_identifier (name), union_type);
286 DECL_ARTIFICIAL (decl) = 1;
287 DECL_IGNORED_P (decl) = 1;
289 if (!gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl))
290 || is_saved)
291 TREE_STATIC (decl) = 1;
293 TREE_ADDRESSABLE (decl) = 1;
294 TREE_USED (decl) = 1;
296 /* The source location has been lost, and doesn't really matter.
297 We need to set it to something though. */
298 gfc_set_decl_location (decl, &gfc_current_locus);
300 gfc_add_decl_to_function (decl);
302 return decl;
306 /* Get storage for common block. */
308 static tree
309 build_common_decl (gfc_common_head *com, tree union_type, bool is_init)
311 gfc_symbol *common_sym;
312 tree decl;
314 /* Create a namespace to store symbols for common blocks. */
315 if (gfc_common_ns == NULL)
316 gfc_common_ns = gfc_get_namespace (NULL, 0);
318 gfc_get_symbol (com->name, gfc_common_ns, &common_sym);
319 decl = common_sym->backend_decl;
321 /* Update the size of this common block as needed. */
322 if (decl != NULL_TREE)
324 tree size = TYPE_SIZE_UNIT (union_type);
325 if (tree_int_cst_lt (DECL_SIZE_UNIT (decl), size))
327 /* Named common blocks of the same name shall be of the same size
328 in all scoping units of a program in which they appear, but
329 blank common blocks may be of different sizes. */
330 if (strcmp (com->name, BLANK_COMMON_NAME))
331 gfc_warning ("Named COMMON block '%s' at %L shall be of the "
332 "same size", com->name, &com->where);
333 DECL_SIZE_UNIT (decl) = size;
337 /* If this common block has been declared in a previous program unit,
338 and either it is already initialized or there is no new initialization
339 for it, just return. */
340 if ((decl != NULL_TREE) && (!is_init || DECL_INITIAL (decl)))
341 return decl;
343 /* If there is no backend_decl for the common block, build it. */
344 if (decl == NULL_TREE)
346 decl = build_decl (VAR_DECL, get_identifier (com->name), union_type);
347 SET_DECL_ASSEMBLER_NAME (decl, gfc_sym_mangled_common_id (com->name));
348 TREE_PUBLIC (decl) = 1;
349 TREE_STATIC (decl) = 1;
350 DECL_ALIGN (decl) = BIGGEST_ALIGNMENT;
351 DECL_USER_ALIGN (decl) = 0;
353 gfc_set_decl_location (decl, &com->where);
355 /* Place the back end declaration for this common block in
356 GLOBAL_BINDING_LEVEL. */
357 common_sym->backend_decl = pushdecl_top_level (decl);
360 /* Has no initial values. */
361 if (!is_init)
363 DECL_INITIAL (decl) = NULL_TREE;
364 DECL_COMMON (decl) = 1;
365 DECL_DEFER_OUTPUT (decl) = 1;
367 else
369 DECL_INITIAL (decl) = error_mark_node;
370 DECL_COMMON (decl) = 0;
371 DECL_DEFER_OUTPUT (decl) = 0;
373 return decl;
377 /* Declare memory for the common block or local equivalence, and create
378 backend declarations for all of the elements. */
380 static void
381 create_common (gfc_common_head *com, segment_info * head, bool saw_equiv)
383 segment_info *s, *next_s;
384 tree union_type;
385 tree *field_link;
386 record_layout_info rli;
387 tree decl;
388 bool is_init = false;
389 bool is_saved = false;
391 /* Declare the variables inside the common block.
392 If the current common block contains any equivalence object, then
393 make a UNION_TYPE node, otherwise RECORD_TYPE. This will let the
394 alias analyzer work well when there is no address overlapping for
395 common variables in the current common block. */
396 if (saw_equiv)
397 union_type = make_node (UNION_TYPE);
398 else
399 union_type = make_node (RECORD_TYPE);
401 rli = start_record_layout (union_type);
402 field_link = &TYPE_FIELDS (union_type);
404 for (s = head; s; s = s->next)
406 build_field (s, union_type, rli);
408 /* Link the field into the type. */
409 *field_link = s->field;
410 field_link = &TREE_CHAIN (s->field);
412 /* Has initial value. */
413 if (s->sym->value)
414 is_init = true;
416 /* Has SAVE attribute. */
417 if (s->sym->attr.save)
418 is_saved = true;
420 finish_record_layout (rli, true);
422 if (com)
423 decl = build_common_decl (com, union_type, is_init);
424 else
425 decl = build_equiv_decl (union_type, is_init, is_saved);
427 if (is_init)
429 tree ctor, tmp;
430 HOST_WIDE_INT offset = 0;
431 VEC(constructor_elt,gc) *v = NULL;
433 for (s = head; s; s = s->next)
435 if (s->sym->value)
437 if (s->offset < offset)
439 /* We have overlapping initializers. It could either be
440 partially initialized arrays (legal), or the user
441 specified multiple initial values (illegal).
442 We don't implement this yet, so bail out. */
443 gfc_todo_error ("Initialization of overlapping variables");
445 /* Add the initializer for this field. */
446 tmp = gfc_conv_initializer (s->sym->value, &s->sym->ts,
447 TREE_TYPE (s->field), s->sym->attr.dimension,
448 s->sym->attr.pointer || s->sym->attr.allocatable);
450 CONSTRUCTOR_APPEND_ELT (v, s->field, tmp);
451 offset = s->offset + s->length;
454 gcc_assert (!VEC_empty (constructor_elt, v));
455 ctor = build_constructor (union_type, v);
456 TREE_CONSTANT (ctor) = 1;
457 TREE_INVARIANT (ctor) = 1;
458 TREE_STATIC (ctor) = 1;
459 DECL_INITIAL (decl) = ctor;
461 #ifdef ENABLE_CHECKING
463 tree field, value;
464 unsigned HOST_WIDE_INT idx;
465 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, field, value)
466 gcc_assert (TREE_CODE (field) == FIELD_DECL);
468 #endif
471 /* Build component reference for each variable. */
472 for (s = head; s; s = next_s)
474 tree var_decl;
476 var_decl = build_decl (VAR_DECL, DECL_NAME (s->field),
477 TREE_TYPE (s->field));
478 gfc_set_decl_location (var_decl, &s->sym->declared_at);
479 TREE_PUBLIC (var_decl) = TREE_PUBLIC (decl);
480 TREE_STATIC (var_decl) = TREE_STATIC (decl);
481 TREE_USED (var_decl) = TREE_USED (decl);
482 if (s->sym->attr.target)
483 TREE_ADDRESSABLE (var_decl) = 1;
484 /* This is a fake variable just for debugging purposes. */
485 TREE_ASM_WRITTEN (var_decl) = 1;
487 if (com)
488 var_decl = pushdecl_top_level (var_decl);
489 else
490 gfc_add_decl_to_function (var_decl);
492 SET_DECL_VALUE_EXPR (var_decl,
493 build3 (COMPONENT_REF, TREE_TYPE (s->field),
494 decl, s->field, NULL_TREE));
495 DECL_HAS_VALUE_EXPR_P (var_decl) = 1;
497 if (s->sym->attr.assign)
499 gfc_allocate_lang_decl (var_decl);
500 GFC_DECL_ASSIGN (var_decl) = 1;
501 GFC_DECL_STRING_LEN (var_decl) = GFC_DECL_STRING_LEN (s->field);
502 GFC_DECL_ASSIGN_ADDR (var_decl) = GFC_DECL_ASSIGN_ADDR (s->field);
505 s->sym->backend_decl = var_decl;
507 next_s = s->next;
508 gfc_free (s);
513 /* Given a symbol, find it in the current segment list. Returns NULL if
514 not found. */
516 static segment_info *
517 find_segment_info (gfc_symbol *symbol)
519 segment_info *n;
521 for (n = current_segment; n; n = n->next)
523 if (n->sym == symbol)
524 return n;
527 return NULL;
531 /* Given an expression node, make sure it is a constant integer and return
532 the mpz_t value. */
534 static mpz_t *
535 get_mpz (gfc_expr *e)
538 if (e->expr_type != EXPR_CONSTANT)
539 gfc_internal_error ("get_mpz(): Not an integer constant");
541 return &e->value.integer;
545 /* Given an array specification and an array reference, figure out the
546 array element number (zero based). Bounds and elements are guaranteed
547 to be constants. If something goes wrong we generate an error and
548 return zero. */
550 static HOST_WIDE_INT
551 element_number (gfc_array_ref *ar)
553 mpz_t multiplier, offset, extent, n;
554 gfc_array_spec *as;
555 HOST_WIDE_INT i, rank;
557 as = ar->as;
558 rank = as->rank;
559 mpz_init_set_ui (multiplier, 1);
560 mpz_init_set_ui (offset, 0);
561 mpz_init (extent);
562 mpz_init (n);
564 for (i = 0; i < rank; i++)
566 if (ar->dimen_type[i] != DIMEN_ELEMENT)
567 gfc_internal_error ("element_number(): Bad dimension type");
569 mpz_sub (n, *get_mpz (ar->start[i]), *get_mpz (as->lower[i]));
571 mpz_mul (n, n, multiplier);
572 mpz_add (offset, offset, n);
574 mpz_sub (extent, *get_mpz (as->upper[i]), *get_mpz (as->lower[i]));
575 mpz_add_ui (extent, extent, 1);
577 if (mpz_sgn (extent) < 0)
578 mpz_set_ui (extent, 0);
580 mpz_mul (multiplier, multiplier, extent);
583 i = mpz_get_ui (offset);
585 mpz_clear (multiplier);
586 mpz_clear (offset);
587 mpz_clear (extent);
588 mpz_clear (n);
590 return i;
594 /* Given a single element of an equivalence list, figure out the offset
595 from the base symbol. For simple variables or full arrays, this is
596 simply zero. For an array element we have to calculate the array
597 element number and multiply by the element size. For a substring we
598 have to calculate the further reference. */
600 static HOST_WIDE_INT
601 calculate_offset (gfc_expr *e)
603 HOST_WIDE_INT n, element_size, offset;
604 gfc_typespec *element_type;
605 gfc_ref *reference;
607 offset = 0;
608 element_type = &e->symtree->n.sym->ts;
610 for (reference = e->ref; reference; reference = reference->next)
611 switch (reference->type)
613 case REF_ARRAY:
614 switch (reference->u.ar.type)
616 case AR_FULL:
617 break;
619 case AR_ELEMENT:
620 n = element_number (&reference->u.ar);
621 if (element_type->type == BT_CHARACTER)
622 gfc_conv_const_charlen (element_type->cl);
623 element_size =
624 int_size_in_bytes (gfc_typenode_for_spec (element_type));
625 offset += n * element_size;
626 break;
628 default:
629 gfc_error ("Bad array reference at %L", &e->where);
631 break;
632 case REF_SUBSTRING:
633 if (reference->u.ss.start != NULL)
634 offset += mpz_get_ui (*get_mpz (reference->u.ss.start)) - 1;
635 break;
636 default:
637 gfc_error ("Illegal reference type at %L as EQUIVALENCE object",
638 &e->where);
640 return offset;
644 /* Add a new segment_info structure to the current segment. eq1 is already
645 in the list, eq2 is not. */
647 static void
648 new_condition (segment_info *v, gfc_equiv *eq1, gfc_equiv *eq2)
650 HOST_WIDE_INT offset1, offset2;
651 segment_info *a;
653 offset1 = calculate_offset (eq1->expr);
654 offset2 = calculate_offset (eq2->expr);
656 a = get_segment_info (eq2->expr->symtree->n.sym,
657 v->offset + offset1 - offset2);
659 current_segment = add_segments (current_segment, a);
663 /* Given two equivalence structures that are both already in the list, make
664 sure that this new condition is not violated, generating an error if it
665 is. */
667 static void
668 confirm_condition (segment_info *s1, gfc_equiv *eq1, segment_info *s2,
669 gfc_equiv *eq2)
671 HOST_WIDE_INT offset1, offset2;
673 offset1 = calculate_offset (eq1->expr);
674 offset2 = calculate_offset (eq2->expr);
676 if (s1->offset + offset1 != s2->offset + offset2)
677 gfc_error ("Inconsistent equivalence rules involving '%s' at %L and "
678 "'%s' at %L", s1->sym->name, &s1->sym->declared_at,
679 s2->sym->name, &s2->sym->declared_at);
683 /* Process a new equivalence condition. eq1 is know to be in segment f.
684 If eq2 is also present then confirm that the condition holds.
685 Otherwise add a new variable to the segment list. */
687 static void
688 add_condition (segment_info *f, gfc_equiv *eq1, gfc_equiv *eq2)
690 segment_info *n;
692 n = find_segment_info (eq2->expr->symtree->n.sym);
694 if (n == NULL)
695 new_condition (f, eq1, eq2);
696 else
697 confirm_condition (f, eq1, n, eq2);
701 /* Given a segment element, search through the equivalence lists for unused
702 conditions that involve the symbol. Add these rules to the segment. */
704 static bool
705 find_equivalence (segment_info *n)
707 gfc_equiv *e1, *e2, *eq;
708 bool found;
710 found = FALSE;
712 for (e1 = n->sym->ns->equiv; e1; e1 = e1->next)
714 eq = NULL;
716 /* Search the equivalence list, including the root (first) element
717 for the symbol that owns the segment. */
718 for (e2 = e1; e2; e2 = e2->eq)
720 if (!e2->used && e2->expr->symtree->n.sym == n->sym)
722 eq = e2;
723 break;
727 /* Go to the next root element. */
728 if (eq == NULL)
729 continue;
731 eq->used = 1;
733 /* Now traverse the equivalence list matching the offsets. */
734 for (e2 = e1; e2; e2 = e2->eq)
736 if (!e2->used && e2 != eq)
738 add_condition (n, eq, e2);
739 e2->used = 1;
740 found = TRUE;
744 return found;
748 /* Add all symbols equivalenced within a segment. We need to scan the
749 segment list multiple times to include indirect equivalences. */
751 static void
752 add_equivalences (bool *saw_equiv)
754 segment_info *f;
755 bool more;
757 more = TRUE;
758 while (more)
760 more = FALSE;
761 for (f = current_segment; f; f = f->next)
763 if (!f->sym->equiv_built)
765 f->sym->equiv_built = 1;
766 more = find_equivalence (f);
767 if (more)
768 *saw_equiv = true;
775 /* Returns the offset necessary to properly align the current equivalence.
776 Sets *palign to the required alignment. */
778 static HOST_WIDE_INT
779 align_segment (unsigned HOST_WIDE_INT * palign)
781 segment_info *s;
782 unsigned HOST_WIDE_INT offset;
783 unsigned HOST_WIDE_INT max_align;
784 unsigned HOST_WIDE_INT this_align;
785 unsigned HOST_WIDE_INT this_offset;
787 max_align = 1;
788 offset = 0;
789 for (s = current_segment; s; s = s->next)
791 this_align = TYPE_ALIGN_UNIT (s->field);
792 if (s->offset & (this_align - 1))
794 /* Field is misaligned. */
795 this_offset = this_align - ((s->offset + offset) & (this_align - 1));
796 if (this_offset & (max_align - 1))
798 /* Aligning this field would misalign a previous field. */
799 gfc_error ("The equivalence set for variable '%s' "
800 "declared at %L violates alignment requirents",
801 s->sym->name, &s->sym->declared_at);
803 offset += this_offset;
805 max_align = this_align;
807 if (palign)
808 *palign = max_align;
809 return offset;
813 /* Adjust segment offsets by the given amount. */
815 static void
816 apply_segment_offset (segment_info * s, HOST_WIDE_INT offset)
818 for (; s; s = s->next)
819 s->offset += offset;
823 /* Lay out a symbol in a common block. If the symbol has already been seen
824 then check the location is consistent. Otherwise create segments
825 for that symbol and all the symbols equivalenced with it. */
827 /* Translate a single common block. */
829 static void
830 translate_common (gfc_common_head *common, gfc_symbol *var_list)
832 gfc_symbol *sym;
833 segment_info *s;
834 segment_info *common_segment;
835 HOST_WIDE_INT offset;
836 HOST_WIDE_INT current_offset;
837 unsigned HOST_WIDE_INT align;
838 unsigned HOST_WIDE_INT max_align;
839 bool saw_equiv;
841 common_segment = NULL;
842 current_offset = 0;
843 max_align = 1;
844 saw_equiv = false;
846 /* Add symbols to the segment. */
847 for (sym = var_list; sym; sym = sym->common_next)
849 current_segment = common_segment;
850 s = find_segment_info (sym);
852 /* Symbol has already been added via an equivalence. Multiple
853 use associations of the same common block result in equiv_built
854 being set but no information about the symbol in the segment. */
855 if (s && sym->equiv_built)
857 /* Ensure the current location is properly aligned. */
858 align = TYPE_ALIGN_UNIT (s->field);
859 current_offset = (current_offset + align - 1) &~ (align - 1);
861 /* Verify that it ended up where we expect it. */
862 if (s->offset != current_offset)
864 gfc_error ("Equivalence for '%s' does not match ordering of "
865 "COMMON '%s' at %L", sym->name,
866 common->name, &common->where);
869 else
871 /* A symbol we haven't seen before. */
872 s = current_segment = get_segment_info (sym, current_offset);
874 /* Add all objects directly or indirectly equivalenced with this
875 symbol. */
876 add_equivalences (&saw_equiv);
878 if (current_segment->offset < 0)
879 gfc_error ("The equivalence set for '%s' cause an invalid "
880 "extension to COMMON '%s' at %L", sym->name,
881 common->name, &common->where);
883 offset = align_segment (&align);
885 if (offset & (max_align - 1))
887 /* The required offset conflicts with previous alignment
888 requirements. Insert padding immediately before this
889 segment. */
890 gfc_warning ("Padding of %d bytes required before '%s' in "
891 "COMMON '%s' at %L", (int)offset, s->sym->name,
892 common->name, &common->where);
894 else
896 /* Offset the whole common block. */
897 apply_segment_offset (common_segment, offset);
900 /* Apply the offset to the new segments. */
901 apply_segment_offset (current_segment, offset);
902 current_offset += offset;
903 if (max_align < align)
904 max_align = align;
906 /* Add the new segments to the common block. */
907 common_segment = add_segments (common_segment, current_segment);
910 /* The offset of the next common variable. */
911 current_offset += s->length;
914 if (common_segment->offset != 0)
916 gfc_warning ("COMMON '%s' at %L requires %d bytes of padding at start",
917 common->name, &common->where, (int)common_segment->offset);
920 create_common (common, common_segment, saw_equiv);
924 /* Create a new block for each merged equivalence list. */
926 static void
927 finish_equivalences (gfc_namespace *ns)
929 gfc_equiv *z, *y;
930 gfc_symbol *sym;
931 gfc_common_head * c;
932 HOST_WIDE_INT offset;
933 unsigned HOST_WIDE_INT align;
934 bool dummy;
936 for (z = ns->equiv; z; z = z->next)
937 for (y = z->eq; y; y = y->eq)
939 if (y->used)
940 continue;
941 sym = z->expr->symtree->n.sym;
942 current_segment = get_segment_info (sym, 0);
944 /* All objects directly or indirectly equivalenced with this symbol. */
945 add_equivalences (&dummy);
947 /* Align the block. */
948 offset = align_segment (&align);
950 /* Ensure all offsets are positive. */
951 offset -= current_segment->offset & ~(align - 1);
953 apply_segment_offset (current_segment, offset);
955 /* Create the decl. If this is a module equivalence, it has a unique
956 name, pointed to by z->module. This is written to a gfc_common_header
957 to push create_common into using build_common_decl, so that the
958 equivalence appears as an external symbol. Otherwise, a local
959 declaration is built using build_equiv_decl.*/
960 if (z->module)
962 c = gfc_get_common_head ();
963 /* We've lost the real location, so use the location of the
964 enclosing procedure. */
965 c->where = ns->proc_name->declared_at;
966 strcpy (c->name, z->module);
968 else
969 c = NULL;
971 create_common (c, current_segment, true);
972 break;
977 /* Work function for translating a named common block. */
979 static void
980 named_common (gfc_symtree *st)
982 translate_common (st->n.common, st->n.common->head);
986 /* Translate the common blocks in a namespace. Unlike other variables,
987 these have to be created before code, because the backend_decl depends
988 on the rest of the common block. */
990 void
991 gfc_trans_common (gfc_namespace *ns)
993 gfc_common_head *c;
995 /* Translate the blank common block. */
996 if (ns->blank_common.head != NULL)
998 c = gfc_get_common_head ();
999 /* We've lost the real location, so use the location of the
1000 enclosing procedure. */
1001 c->where = ns->proc_name->declared_at;
1002 strcpy (c->name, BLANK_COMMON_NAME);
1003 translate_common (c, ns->blank_common.head);
1006 /* Translate all named common blocks. */
1007 gfc_traverse_symtree (ns->common_root, named_common);
1009 /* Commit the newly created symbols for common blocks. */
1010 gfc_commit_symbols ();
1012 /* Translate local equivalence. */
1013 finish_equivalences (ns);