Typo in last patch.
[official-gcc.git] / gcc / fortran / trans-common.c
blob667038d5cc45202cc3309c46ee35b52fbbcfc32a
1 /* Common block and equivalence list handling
2 Copyright (C) 2000, 2003 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, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, 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 equvalence 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"
106 #include <assert.h>
109 typedef struct segment_info
111 gfc_symbol *sym;
112 HOST_WIDE_INT offset;
113 HOST_WIDE_INT length;
114 tree field;
115 struct segment_info *next;
116 } segment_info;
118 static segment_info *current_segment, *current_common;
119 static HOST_WIDE_INT current_offset;
120 static gfc_namespace *gfc_common_ns = NULL;
122 #define get_segment_info() gfc_getmem (sizeof (segment_info))
124 #define BLANK_COMMON_NAME "__BLNK__"
127 /* Add combine segment V and segement LIST. */
129 static segment_info *
130 add_segments (segment_info *list, segment_info *v)
132 segment_info *s;
133 segment_info *p;
134 segment_info *next;
136 p = NULL;
137 s = list;
139 while (v)
141 /* Find the location of the new element. */
142 while (s)
144 if (v->offset < s->offset)
145 break;
146 if (v->offset == s->offset
147 && v->length <= s->length)
148 break;
150 p = s;
151 s = s->next;
154 /* Insert the new element in between p and s. */
155 next = v->next;
156 v->next = s;
157 if (p == NULL)
158 list = v;
159 else
160 p->next = v;
162 p = v;
163 v = next;
165 return list;
168 /* Construct mangled common block name from symbol name. */
170 static tree
171 gfc_sym_mangled_common_id (gfc_symbol *sym)
173 int has_underscore;
174 char name[GFC_MAX_MANGLED_SYMBOL_LEN + 1];
176 if (strcmp (sym->name, BLANK_COMMON_NAME) == 0)
177 return get_identifier (sym->name);
178 if (gfc_option.flag_underscoring)
180 has_underscore = strchr (sym->name, '_') != 0;
181 if (gfc_option.flag_second_underscore && has_underscore)
182 snprintf (name, sizeof name, "%s__", sym->name);
183 else
184 snprintf (name, sizeof name, "%s_", sym->name);
185 return get_identifier (name);
187 else
188 return get_identifier (sym->name);
192 /* Build a filed declaration for a common variable or a local equivalence
193 object. */
195 static tree
196 build_field (segment_info *h, tree union_type, record_layout_info rli)
198 tree type = gfc_sym_type (h->sym);
199 tree name = get_identifier (h->sym->name);
200 tree field = build_decl (FIELD_DECL, name, type);
201 HOST_WIDE_INT offset = h->offset;
202 unsigned HOST_WIDE_INT desired_align, known_align;
204 known_align = (offset & -offset) * BITS_PER_UNIT;
205 if (known_align == 0 || known_align > BIGGEST_ALIGNMENT)
206 known_align = BIGGEST_ALIGNMENT;
208 desired_align = update_alignment_for_field (rli, field, known_align);
209 if (desired_align > known_align)
210 DECL_PACKED (field) = 1;
212 DECL_FIELD_CONTEXT (field) = union_type;
213 DECL_FIELD_OFFSET (field) = size_int (offset);
214 DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
215 SET_DECL_OFFSET_ALIGN (field, known_align);
217 rli->offset = size_binop (MAX_EXPR, rli->offset,
218 size_binop (PLUS_EXPR,
219 DECL_FIELD_OFFSET (field),
220 DECL_SIZE_UNIT (field)));
221 return field;
225 /* Get storage for local equivalence. */
227 static tree
228 build_equiv_decl (tree union_type, bool is_init)
230 tree decl;
232 if (is_init)
234 decl = gfc_create_var (union_type, "equiv");
235 TREE_STATIC (decl) = 1;
236 return decl;
239 decl = build_decl (VAR_DECL, NULL, union_type);
240 DECL_ARTIFICIAL (decl) = 1;
242 DECL_COMMON (decl) = 1;
244 TREE_ADDRESSABLE (decl) = 1;
245 TREE_USED (decl) = 1;
246 gfc_add_decl_to_function (decl);
248 return decl;
252 /* Get storage for common block. */
254 static tree
255 build_common_decl (gfc_symbol *sym, tree union_type, bool is_init)
257 gfc_symbol *common_sym;
258 tree decl;
260 /* Create a namespace to store symbols for common blocks. */
261 if (gfc_common_ns == NULL)
262 gfc_common_ns = gfc_get_namespace (NULL);
264 gfc_get_symbol (sym->name, gfc_common_ns, &common_sym);
265 decl = common_sym->backend_decl;
267 /* Update the size of this common block as needed. */
268 if (decl != NULL_TREE)
270 tree size = TYPE_SIZE_UNIT (union_type);
271 if (tree_int_cst_lt (DECL_SIZE_UNIT (decl), size))
273 /* Named common blocks of the same name shall be of the same size
274 in all scoping units of a program in which they appear, but
275 blank common blocks may be of different sizes. */
276 if (strcmp (sym->name, BLANK_COMMON_NAME))
277 gfc_warning ("Named COMMON block '%s' at %L shall be of the "
278 "same size", sym->name, &sym->declared_at);
279 DECL_SIZE_UNIT (decl) = size;
283 /* If this common block has been declared in a previous program unit,
284 and either it is already initialized or there is no new initialization
285 for it, just return. */
286 if ((decl != NULL_TREE) && (!is_init || DECL_INITIAL (decl)))
287 return decl;
289 /* If there is no backend_decl for the common block, build it. */
290 if (decl == NULL_TREE)
292 decl = build_decl (VAR_DECL, get_identifier (sym->name), union_type);
293 SET_DECL_ASSEMBLER_NAME (decl, gfc_sym_mangled_common_id (sym));
294 TREE_PUBLIC (decl) = 1;
295 TREE_STATIC (decl) = 1;
296 DECL_ALIGN (decl) = BIGGEST_ALIGNMENT;
297 DECL_USER_ALIGN (decl) = 0;
299 /* Place the back end declaration for this common block in
300 GLOBAL_BINDING_LEVEL. */
301 common_sym->backend_decl = pushdecl_top_level (decl);
304 /* Has no initial values. */
305 if (!is_init)
307 DECL_INITIAL (decl) = NULL_TREE;
308 DECL_COMMON (decl) = 1;
309 DECL_DEFER_OUTPUT (decl) = 1;
312 else
314 DECL_INITIAL (decl) = error_mark_node;
315 DECL_COMMON (decl) = 0;
316 DECL_DEFER_OUTPUT (decl) = 0;
318 return decl;
322 /* Declare memory for the common block or local equivalence, and create
323 backend declarations for all of the elements. */
325 static void
326 create_common (gfc_symbol *sym)
328 segment_info *h, *next_s;
329 tree union_type;
330 tree *field_link;
331 record_layout_info rli;
332 tree decl;
333 bool is_init = false;
335 /* Declare the variables inside the common block. */
336 union_type = make_node (UNION_TYPE);
337 rli = start_record_layout (union_type);
338 field_link = &TYPE_FIELDS (union_type);
340 for (h = current_common; h; h = next_s)
342 tree field;
343 field = build_field (h, union_type, rli);
345 /* Link the field into the type. */
346 *field_link = field;
347 field_link = &TREE_CHAIN (field);
348 h->field = field;
349 /* Has initial value. */
350 if (h->sym->value)
351 is_init = true;
353 next_s = h->next;
355 finish_record_layout (rli, true);
357 if (sym)
358 decl = build_common_decl (sym, union_type, is_init);
359 else
360 decl = build_equiv_decl (union_type, is_init);
362 if (is_init)
364 tree list, ctor, tmp;
365 gfc_se se;
366 HOST_WIDE_INT offset = 0;
368 list = NULL_TREE;
369 for (h = current_common; h; h = h->next)
371 if (h->sym->value)
373 if (h->offset < offset)
375 /* We have overlapping initializers. It could either be
376 partially initilalized arrays (lagal), or the user
377 specified multiple initial values (illegal).
378 We don't implement this yet, so bail out. */
379 gfc_todo_error ("Initialization of overlapping variables");
381 if (h->sym->attr.dimension)
383 tmp = gfc_conv_array_initializer (TREE_TYPE (h->field),
384 h->sym->value);
385 list = tree_cons (h->field, tmp, list);
387 else
389 switch (h->sym->ts.type)
391 case BT_CHARACTER:
392 se.expr = gfc_conv_string_init
393 (h->sym->ts.cl->backend_decl, h->sym->value);
394 break;
396 case BT_DERIVED:
397 gfc_init_se (&se, NULL);
398 gfc_conv_structure (&se, sym->value, 1);
399 break;
401 default:
402 gfc_init_se (&se, NULL);
403 gfc_conv_expr (&se, h->sym->value);
404 break;
406 list = tree_cons (h->field, se.expr, list);
408 offset = h->offset + h->length;
411 assert (list);
412 ctor = build1 (CONSTRUCTOR, union_type, nreverse(list));
413 TREE_CONSTANT (ctor) = 1;
414 TREE_INVARIANT (ctor) = 1;
415 TREE_STATIC (ctor) = 1;
416 DECL_INITIAL (decl) = ctor;
418 #ifdef ENABLE_CHECKING
419 for (tmp = CONSTRUCTOR_ELTS (ctor); tmp; tmp = TREE_CHAIN (tmp))
420 assert (TREE_CODE (TREE_PURPOSE (tmp)) == FIELD_DECL);
421 #endif
424 /* Build component reference for each variable. */
425 for (h = current_common; h; h = next_s)
427 h->sym->backend_decl = build (COMPONENT_REF, TREE_TYPE (h->field),
428 decl, h->field);
430 next_s = h->next;
431 gfc_free (h);
436 /* Given a symbol, find it in the current segment list. Returns NULL if
437 not found. */
439 static segment_info *
440 find_segment_info (gfc_symbol *symbol)
442 segment_info *n;
444 for (n = current_segment; n; n = n->next)
446 if (n->sym == symbol)
447 return n;
450 return NULL;
454 /* Given a variable symbol, calculate the total length in bytes of the
455 variable. */
457 static HOST_WIDE_INT
458 calculate_length (gfc_symbol *symbol)
460 HOST_WIDE_INT j, element_size;
461 mpz_t elements;
463 if (symbol->ts.type == BT_CHARACTER)
464 gfc_conv_const_charlen (symbol->ts.cl);
465 element_size = int_size_in_bytes (gfc_typenode_for_spec (&symbol->ts));
466 if (symbol->as == NULL)
467 return element_size;
469 /* Calculate the number of elements in the array */
470 if (spec_size (symbol->as, &elements) == FAILURE)
471 gfc_internal_error ("calculate_length(): Unable to determine array size");
472 j = mpz_get_ui (elements);
473 mpz_clear (elements);
475 return j*element_size;;
479 /* Given an expression node, make sure it is a constant integer and return
480 the mpz_t value. */
482 static mpz_t *
483 get_mpz (gfc_expr *g)
485 if (g->expr_type != EXPR_CONSTANT)
486 gfc_internal_error ("get_mpz(): Not an integer constant");
488 return &g->value.integer;
492 /* Given an array specification and an array reference, figure out the
493 array element number (zero based). Bounds and elements are guaranteed
494 to be constants. If something goes wrong we generate an error and
495 return zero. */
497 static HOST_WIDE_INT
498 element_number (gfc_array_ref *ar)
500 mpz_t multiplier, offset, extent, l;
501 gfc_array_spec *as;
502 HOST_WIDE_INT b, rank;
504 as = ar->as;
505 rank = as->rank;
506 mpz_init_set_ui (multiplier, 1);
507 mpz_init_set_ui (offset, 0);
508 mpz_init (extent);
509 mpz_init (l);
511 for (b = 0; b < rank; b++)
513 if (ar->dimen_type[b] != DIMEN_ELEMENT)
514 gfc_internal_error ("element_number(): Bad dimension type");
516 mpz_sub (l, *get_mpz (ar->start[b]), *get_mpz (as->lower[b]));
518 mpz_mul (l, l, multiplier);
519 mpz_add (offset, offset, l);
521 mpz_sub (extent, *get_mpz (as->upper[b]), *get_mpz (as->lower[b]));
522 mpz_add_ui (extent, extent, 1);
524 if (mpz_sgn (extent) < 0)
525 mpz_set_ui (extent, 0);
527 mpz_mul (multiplier, multiplier, extent);
530 b = mpz_get_ui (offset);
532 mpz_clear (multiplier);
533 mpz_clear (offset);
534 mpz_clear (extent);
535 mpz_clear (l);
537 return b;
541 /* Given a single element of an equivalence list, figure out the offset
542 from the base symbol. For simple variables or full arrays, this is
543 simply zero. For an array element we have to calculate the array
544 element number and multiply by the element size. For a substring we
545 have to calculate the further reference. */
547 static HOST_WIDE_INT
548 calculate_offset (gfc_expr *s)
550 HOST_WIDE_INT a, element_size, offset;
551 gfc_typespec *element_type;
552 gfc_ref *reference;
554 offset = 0;
555 element_type = &s->symtree->n.sym->ts;
557 for (reference = s->ref; reference; reference = reference->next)
558 switch (reference->type)
560 case REF_ARRAY:
561 switch (reference->u.ar.type)
563 case AR_FULL:
564 break;
566 case AR_ELEMENT:
567 a = element_number (&reference->u.ar);
568 if (element_type->type == BT_CHARACTER)
569 gfc_conv_const_charlen (element_type->cl);
570 element_size =
571 int_size_in_bytes (gfc_typenode_for_spec (element_type));
572 offset += a * element_size;
573 break;
575 default:
576 gfc_error ("Bad array reference at %L", &s->where);
578 break;
579 case REF_SUBSTRING:
580 if (reference->u.ss.start != NULL)
581 offset += mpz_get_ui (*get_mpz (reference->u.ss.start)) - 1;
582 break;
583 default:
584 gfc_error ("Illegal reference type at %L as EQUIVALENCE object",
585 &s->where);
587 return offset;
591 /* Add a new segment_info structure to the current segment. eq1 is already
592 in the list, eq2 is not. */
594 static void
595 new_condition (segment_info *v, gfc_equiv *eq1, gfc_equiv *eq2)
597 HOST_WIDE_INT offset1, offset2;
598 segment_info *a;
600 offset1 = calculate_offset (eq1->expr);
601 offset2 = calculate_offset (eq2->expr);
603 a = get_segment_info ();
605 a->sym = eq2->expr->symtree->n.sym;
606 a->offset = v->offset + offset1 - offset2;
607 a->length = calculate_length (eq2->expr->symtree->n.sym);
609 current_segment = add_segments (current_segment, a);
613 /* Given two equivalence structures that are both already in the list, make
614 sure that this new condition is not violated, generating an error if it
615 is. */
617 static void
618 confirm_condition (segment_info *k, gfc_equiv *eq1, segment_info *e,
619 gfc_equiv *eq2)
621 HOST_WIDE_INT offset1, offset2;
623 offset1 = calculate_offset (eq1->expr);
624 offset2 = calculate_offset (eq2->expr);
626 if (k->offset + offset1 != e->offset + offset2)
627 gfc_error ("Inconsistent equivalence rules involving '%s' at %L and "
628 "'%s' at %L", k->sym->name, &k->sym->declared_at,
629 e->sym->name, &e->sym->declared_at);
633 /* Process a new equivalence condition. eq1 is know to be in segment f.
634 If eq2 is also present then confirm that the condition holds.
635 Otherwise add a new variable to the segment list. */
637 static void
638 add_condition (segment_info *f, gfc_equiv *eq1, gfc_equiv *eq2)
640 segment_info *n;
642 n = find_segment_info (eq2->expr->symtree->n.sym);
644 if (n == NULL)
645 new_condition (f, eq1, eq2);
646 else
647 confirm_condition (f, eq1, n, eq2);
651 /* Given a segment element, search through the equivalence lists for unused
652 conditions that involve the symbol. Add these rules to the segment. Only
653 checks for rules involving the first symbol in the equivalence set. */
655 static bool
656 find_equivalence (segment_info *f)
658 gfc_equiv *c, *l, *eq, *other;
659 bool found;
661 found = FALSE;
662 for (c = f->sym->ns->equiv; c; c = c->next)
664 other = NULL;
665 for (l = c->eq; l; l = l->eq)
667 if (l->used)
668 continue;
670 if (c->expr->symtree->n.sym == f-> sym)
672 eq = c;
673 other = l;
675 else if (l->expr->symtree->n.sym == f->sym)
677 eq = l;
678 other = c;
680 else
681 eq = NULL;
683 if (eq)
685 add_condition (f, eq, other);
686 eq->used = 1;
687 found = TRUE;
688 /* If this symbol is the first in the chain we may find other
689 matches. Otherwise we can skip to the next equivalence. */
690 if (eq == l)
691 break;
695 return found;
699 /* Add all symbols equivalenced within a segment. We need to scan the
700 segment list multiple times to include indirect equivalences. */
702 static void
703 add_equivalences (void)
705 segment_info *f;
706 bool more;
708 more = TRUE;
709 while (more)
711 more = FALSE;
712 for (f = current_segment; f; f = f->next)
714 if (!f->sym->equiv_built)
716 f->sym->equiv_built = 1;
717 more = find_equivalence (f);
724 /* Given a seed symbol, create a new segment consisting of that symbol
725 and all of the symbols equivalenced with that symbol. */
727 static void
728 new_segment (gfc_symbol *common_sym, gfc_symbol *sym)
730 HOST_WIDE_INT length;
732 current_segment = get_segment_info ();
733 current_segment->sym = sym;
734 current_segment->offset = current_offset;
735 length = calculate_length (sym);
736 current_segment->length = length;
738 /* Add all object directly or indirectly equivalenced with this common
739 variable. */
740 add_equivalences ();
742 if (current_segment->offset < 0)
743 gfc_error ("The equivalence set for '%s' cause an invalid extension "
744 "to COMMON '%s' at %L",
745 sym->name, common_sym->name, &common_sym->declared_at);
747 /* The offset of the next common variable. */
748 current_offset += length;
750 /* Add these to the common block. */
751 current_common = add_segments (current_common, current_segment);
755 /* Create a new block for each merged equivalence list. */
757 static void
758 finish_equivalences (gfc_namespace *ns)
760 gfc_equiv *z, *y;
761 gfc_symbol *sym;
762 segment_info *v;
763 HOST_WIDE_INT min_offset;
765 for (z = ns->equiv; z; z = z->next)
766 for (y= z->eq; y; y = y->eq)
768 if (y->used) continue;
769 sym = z->expr->symtree->n.sym;
770 current_segment = get_segment_info ();
771 current_segment->sym = sym;
772 current_segment->offset = 0;
773 current_segment->length = calculate_length (sym);
775 /* All objects directly or indrectly equivalenced with this symbol. */
776 add_equivalences ();
778 /* Calculate the minimal offset. */
779 min_offset = current_segment->offset;
781 /* Adjust the offset of each equivalence object. */
782 for (v = current_segment; v; v = v->next)
783 v->offset -= min_offset;
785 current_common = current_segment;
786 create_common (NULL);
787 break;
792 /* Translate a single common block. */
794 static void
795 translate_common (gfc_symbol *common_sym, gfc_symbol *var_list)
797 gfc_symbol *sym;
799 current_common = NULL;
800 current_offset = 0;
802 /* Add symbols to the segment. */
803 for (sym = var_list; sym; sym = sym->common_next)
805 if (! sym->equiv_built)
806 new_segment (common_sym, sym);
809 create_common (common_sym);
813 /* Work function for translating a named common block. */
815 static void
816 named_common (gfc_symbol *s)
818 if (s->attr.common)
819 translate_common (s, s->common_head);
823 /* Translate the common blocks in a namespace. Unlike other variables,
824 these have to be created before code, because the backend_decl depends
825 on the rest of the common block. */
827 void
828 gfc_trans_common (gfc_namespace *ns)
830 gfc_symbol *sym;
832 /* Translate the blank common block. */
833 if (ns->blank_common != NULL)
835 gfc_get_symbol (BLANK_COMMON_NAME, ns, &sym);
836 translate_common (sym, ns->blank_common);
839 /* Translate all named common blocks. */
840 gfc_traverse_ns (ns, named_common);
842 /* Commit the newly created symbols for common blocks. */
843 gfc_commit_symbols ();
845 /* Translate local equivalence. */
846 finish_equivalences (ns);