OSDN Git Service

Update FSF address.
[pf3gnuchains/gcc-fork.git] / gcc / fortran / trans-common.c
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>
4
5 This file is part of GCC.
6
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.
11
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.
16
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.  */     
21
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.
24  
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.
28
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. 
32  
33    So if two variables are equivalenced, they just point to a common
34    area in memory.
35  
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.
44  
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.
55  
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.
61  
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
66  
67      EQUIVALENCE(B(2), C(3))
68    we have
69      B + 2*size of B's elements = C + 3*size of C's elements.
70  
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.
77  
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.
84  
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. 
91    
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.  */
95
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
107
108 /* Holds a single variable in a equivalence set.  */
109 typedef struct segment_info
110 {
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;
118
119 static segment_info * current_segment;
120 static gfc_namespace *gfc_common_ns = NULL;
121
122 #define BLANK_COMMON_NAME "__BLNK__"
123
124 /* Make a segment_info based on a symbol.  */
125
126 static segment_info *
127 get_segment_info (gfc_symbol * sym, HOST_WIDE_INT offset)
128 {
129   segment_info *s;
130
131   /* Make sure we've got the character length.  */
132   if (sym->ts.type == BT_CHARACTER)
133     gfc_conv_const_charlen (sym->ts.cl);
134
135   /* Create the segment_info and fill it in.  */
136   s = (segment_info *) gfc_getmem (sizeof (segment_info));
137   s->sym = sym;
138   /* We will use this type when building the segment aggregate type.  */
139   s->field = gfc_sym_type (sym);
140   s->length = int_size_in_bytes (s->field);
141   s->offset = offset;
142
143   return s;
144 }
145
146 /* Add combine segment V and segment LIST.  */
147
148 static segment_info *
149 add_segments (segment_info *list, segment_info *v)
150 {
151   segment_info *s;
152   segment_info *p;
153   segment_info *next;
154
155   p = NULL;
156   s = list;
157
158   while (v)
159     {
160       /* Find the location of the new element.  */
161       while (s)
162         {
163           if (v->offset < s->offset)
164             break;
165           if (v->offset == s->offset
166               && v->length <= s->length)
167             break;
168
169           p = s;
170           s = s->next;
171         }
172
173       /* Insert the new element in between p and s.  */
174       next = v->next;
175       v->next = s;
176       if (p == NULL)
177         list = v;
178       else
179         p->next = v;
180
181       p = v;
182       v = next;
183     }
184
185   return list;
186 }
187
188 /* Construct mangled common block name from symbol name.  */
189
190 static tree
191 gfc_sym_mangled_common_id (const char  *name)
192 {
193   int has_underscore;
194   char mangled_name[GFC_MAX_MANGLED_SYMBOL_LEN + 1];
195
196   if (strcmp (name, BLANK_COMMON_NAME) == 0)
197     return get_identifier (name);
198
199   if (gfc_option.flag_underscoring)
200     {
201       has_underscore = strchr (name, '_') != 0;
202       if (gfc_option.flag_second_underscore && has_underscore)
203         snprintf (mangled_name, sizeof mangled_name, "%s__", name);
204       else
205         snprintf (mangled_name, sizeof mangled_name, "%s_", name);
206
207       return get_identifier (mangled_name);
208     }
209   else
210     return get_identifier (name);
211 }
212
213
214 /* Build a field declaration for a common variable or a local equivalence
215    object.  */
216
217 static void
218 build_field (segment_info *h, tree union_type, record_layout_info rli)
219 {
220   tree field;
221   tree name;
222   HOST_WIDE_INT offset = h->offset;
223   unsigned HOST_WIDE_INT desired_align, known_align;
224
225   name = get_identifier (h->sym->name);
226   field = build_decl (FIELD_DECL, name, h->field);
227   gfc_set_decl_location (field, &h->sym->declared_at);
228   known_align = (offset & -offset) * BITS_PER_UNIT;
229   if (known_align == 0 || known_align > BIGGEST_ALIGNMENT)
230     known_align = BIGGEST_ALIGNMENT;
231
232   desired_align = update_alignment_for_field (rli, field, known_align);
233   if (desired_align > known_align)
234     DECL_PACKED (field) = 1;
235
236   DECL_FIELD_CONTEXT (field) = union_type;
237   DECL_FIELD_OFFSET (field) = size_int (offset);
238   DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
239   SET_DECL_OFFSET_ALIGN (field, known_align);
240
241   rli->offset = size_binop (MAX_EXPR, rli->offset,
242                             size_binop (PLUS_EXPR,
243                                         DECL_FIELD_OFFSET (field),
244                                         DECL_SIZE_UNIT (field)));
245   /* If this field is assigned to a label, we create another two variables.
246      One will hold the address of taget label or format label. The other will
247      hold the length of format label string.  */
248   if (h->sym->attr.assign)
249     {
250       tree len;
251       tree addr;
252
253       gfc_allocate_lang_decl (field);
254       GFC_DECL_ASSIGN (field) = 1;
255       len = gfc_create_var_np (gfc_charlen_type_node,h->sym->name);
256       addr = gfc_create_var_np (pvoid_type_node, h->sym->name);
257       TREE_STATIC (len) = 1;
258       TREE_STATIC (addr) = 1;
259       DECL_INITIAL (len) = build_int_cst (NULL_TREE, -2);
260       gfc_set_decl_location (len, &h->sym->declared_at);
261       gfc_set_decl_location (addr, &h->sym->declared_at);
262       GFC_DECL_STRING_LEN (field) = pushdecl_top_level (len);
263       GFC_DECL_ASSIGN_ADDR (field) = pushdecl_top_level (addr);
264     }
265
266   h->field = field;
267 }
268
269
270 /* Get storage for local equivalence.  */
271
272 static tree
273 build_equiv_decl (tree union_type, bool is_init)
274 {
275   tree decl;
276   char name[15];
277   static int serial = 0;
278
279   if (is_init)
280     {
281       decl = gfc_create_var (union_type, "equiv");
282       TREE_STATIC (decl) = 1;
283       return decl;
284     }
285
286   snprintf (name, sizeof (name), "equiv.%d", serial++);
287   decl = build_decl (VAR_DECL, get_identifier (name), union_type);
288   DECL_ARTIFICIAL (decl) = 1;
289   DECL_IGNORED_P (decl) = 1;
290
291   if (!gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl)))
292     TREE_STATIC (decl) = 1;
293
294   TREE_ADDRESSABLE (decl) = 1;
295   TREE_USED (decl) = 1;
296
297   /* The source location has been lost, and doesn't really matter.
298      We need to set it to something though.  */
299   gfc_set_decl_location (decl, &gfc_current_locus);
300
301   gfc_add_decl_to_function (decl);
302
303   return decl;
304 }
305
306
307 /* Get storage for common block.  */
308
309 static tree
310 build_common_decl (gfc_common_head *com, tree union_type, bool is_init)
311 {
312   gfc_symbol *common_sym;
313   tree decl;
314
315   /* Create a namespace to store symbols for common blocks.  */
316   if (gfc_common_ns == NULL)
317     gfc_common_ns = gfc_get_namespace (NULL, 0);
318
319   gfc_get_symbol (com->name, gfc_common_ns, &common_sym);
320   decl = common_sym->backend_decl;
321
322   /* Update the size of this common block as needed.  */
323   if (decl != NULL_TREE)
324     {
325       tree size = TYPE_SIZE_UNIT (union_type);
326       if (tree_int_cst_lt (DECL_SIZE_UNIT (decl), size))
327         {
328           /* Named common blocks of the same name shall be of the same size
329              in all scoping units of a program in which they appear, but
330              blank common blocks may be of different sizes.  */
331           if (strcmp (com->name, BLANK_COMMON_NAME))
332             gfc_warning ("Named COMMON block '%s' at %L shall be of the "
333                          "same size", com->name, &com->where);
334           DECL_SIZE_UNIT (decl) = size;
335         }
336      }
337
338   /* If this common block has been declared in a previous program unit,
339      and either it is already initialized or there is no new initialization
340      for it, just return.  */
341   if ((decl != NULL_TREE) && (!is_init || DECL_INITIAL (decl)))
342     return decl;
343
344   /* If there is no backend_decl for the common block, build it.  */
345   if (decl == NULL_TREE)
346     {
347       decl = build_decl (VAR_DECL, get_identifier (com->name), union_type);
348       SET_DECL_ASSEMBLER_NAME (decl, gfc_sym_mangled_common_id (com->name));
349       TREE_PUBLIC (decl) = 1;
350       TREE_STATIC (decl) = 1;
351       DECL_ALIGN (decl) = BIGGEST_ALIGNMENT;
352       DECL_USER_ALIGN (decl) = 0;
353
354       gfc_set_decl_location (decl, &com->where);
355
356       /* Place the back end declaration for this common block in
357          GLOBAL_BINDING_LEVEL.  */
358       common_sym->backend_decl = pushdecl_top_level (decl);
359     }
360
361   /* Has no initial values.  */
362   if (!is_init)
363     {
364       DECL_INITIAL (decl) = NULL_TREE;
365       DECL_COMMON (decl) = 1;
366       DECL_DEFER_OUTPUT (decl) = 1;
367     }
368   else
369     {
370       DECL_INITIAL (decl) = error_mark_node;
371       DECL_COMMON (decl) = 0;
372       DECL_DEFER_OUTPUT (decl) = 0;
373     }
374   return decl;
375 }
376
377
378 /* Declare memory for the common block or local equivalence, and create
379    backend declarations for all of the elements.  */
380
381 static void
382 create_common (gfc_common_head *com, segment_info * head, bool saw_equiv)
383 {
384   segment_info *s, *next_s;
385   tree union_type;
386   tree *field_link;
387   record_layout_info rli;
388   tree decl;
389   bool is_init = false;
390
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);
400
401   rli = start_record_layout (union_type);
402   field_link = &TYPE_FIELDS (union_type);
403
404   for (s = head; s; s = s->next)
405     {
406       build_field (s, union_type, rli);
407
408       /* Link the field into the type.  */
409       *field_link = s->field;
410       field_link = &TREE_CHAIN (s->field);
411
412       /* Has initial value.  */
413       if (s->sym->value)
414         is_init = true;
415     }
416   finish_record_layout (rli, true);
417
418   if (com)
419     decl = build_common_decl (com, union_type, is_init);
420   else
421     decl = build_equiv_decl (union_type, is_init);
422
423   if (is_init)
424     {
425       tree list, ctor, tmp;
426       HOST_WIDE_INT offset = 0;
427
428       list = NULL_TREE;
429       for (s = head; s; s = s->next)
430         {
431           if (s->sym->value)
432             {
433               if (s->offset < offset)
434                 {
435                     /* We have overlapping initializers.  It could either be
436                        partially initialized arrays (legal), or the user
437                        specified multiple initial values (illegal).
438                        We don't implement this yet, so bail out.  */
439                   gfc_todo_error ("Initialization of overlapping variables");
440                 }
441               /* Add the initializer for this field.  */
442               tmp = gfc_conv_initializer (s->sym->value, &s->sym->ts,
443                   TREE_TYPE (s->field), s->sym->attr.dimension,
444                   s->sym->attr.pointer || s->sym->attr.allocatable);
445               list = tree_cons (s->field, tmp, list);
446               offset = s->offset + s->length;
447             }
448         }
449       gcc_assert (list);
450       ctor = build1 (CONSTRUCTOR, union_type, nreverse(list));
451       TREE_CONSTANT (ctor) = 1;
452       TREE_INVARIANT (ctor) = 1;
453       TREE_STATIC (ctor) = 1;
454       DECL_INITIAL (decl) = ctor;
455
456 #ifdef ENABLE_CHECKING
457       for (tmp = CONSTRUCTOR_ELTS (ctor); tmp; tmp = TREE_CHAIN (tmp))
458         gcc_assert (TREE_CODE (TREE_PURPOSE (tmp)) == FIELD_DECL);
459 #endif
460     }
461
462   /* Build component reference for each variable.  */
463   for (s = head; s; s = next_s)
464     {
465       s->sym->backend_decl = build3 (COMPONENT_REF, TREE_TYPE (s->field),
466                                 decl, s->field, NULL_TREE);
467
468       next_s = s->next;
469       gfc_free (s);
470     }
471 }
472
473
474 /* Given a symbol, find it in the current segment list. Returns NULL if
475    not found.  */
476
477 static segment_info *
478 find_segment_info (gfc_symbol *symbol)
479 {
480   segment_info *n;
481
482   for (n = current_segment; n; n = n->next)
483     {
484       if (n->sym == symbol)
485         return n;
486     }
487
488   return NULL;
489 }
490
491
492 /* Given an expression node, make sure it is a constant integer and return
493    the mpz_t value.  */
494
495 static mpz_t *
496 get_mpz (gfc_expr *e)
497 {
498
499   if (e->expr_type != EXPR_CONSTANT)
500     gfc_internal_error ("get_mpz(): Not an integer constant");
501
502   return &e->value.integer;
503 }
504
505
506 /* Given an array specification and an array reference, figure out the
507    array element number (zero based). Bounds and elements are guaranteed
508    to be constants.  If something goes wrong we generate an error and
509    return zero.  */
510  
511 static HOST_WIDE_INT
512 element_number (gfc_array_ref *ar)
513 {
514   mpz_t multiplier, offset, extent, n;
515   gfc_array_spec *as;
516   HOST_WIDE_INT i, rank;
517
518   as = ar->as;
519   rank = as->rank;
520   mpz_init_set_ui (multiplier, 1);
521   mpz_init_set_ui (offset, 0);
522   mpz_init (extent);
523   mpz_init (n);
524
525   for (i = 0; i < rank; i++)
526     { 
527       if (ar->dimen_type[i] != DIMEN_ELEMENT)
528         gfc_internal_error ("element_number(): Bad dimension type");
529
530       mpz_sub (n, *get_mpz (ar->start[i]), *get_mpz (as->lower[i]));
531  
532       mpz_mul (n, n, multiplier);
533       mpz_add (offset, offset, n);
534  
535       mpz_sub (extent, *get_mpz (as->upper[i]), *get_mpz (as->lower[i]));
536       mpz_add_ui (extent, extent, 1);
537  
538       if (mpz_sgn (extent) < 0)
539         mpz_set_ui (extent, 0);
540  
541       mpz_mul (multiplier, multiplier, extent);
542     } 
543  
544   i = mpz_get_ui (offset);
545  
546   mpz_clear (multiplier);
547   mpz_clear (offset);
548   mpz_clear (extent);
549   mpz_clear (n);
550  
551   return i;
552 }
553
554
555 /* Given a single element of an equivalence list, figure out the offset
556    from the base symbol.  For simple variables or full arrays, this is
557    simply zero.  For an array element we have to calculate the array
558    element number and multiply by the element size. For a substring we
559    have to calculate the further reference.  */
560
561 static HOST_WIDE_INT
562 calculate_offset (gfc_expr *e)
563 {
564   HOST_WIDE_INT n, element_size, offset;
565   gfc_typespec *element_type;
566   gfc_ref *reference;
567
568   offset = 0;
569   element_type = &e->symtree->n.sym->ts;
570
571   for (reference = e->ref; reference; reference = reference->next)
572     switch (reference->type)
573       {
574       case REF_ARRAY:
575         switch (reference->u.ar.type)
576           {
577           case AR_FULL:
578             break;
579
580           case AR_ELEMENT:
581             n = element_number (&reference->u.ar);
582             if (element_type->type == BT_CHARACTER)
583               gfc_conv_const_charlen (element_type->cl);
584             element_size =
585               int_size_in_bytes (gfc_typenode_for_spec (element_type));
586             offset += n * element_size;
587             break;
588
589           default:
590             gfc_error ("Bad array reference at %L", &e->where);
591           }
592         break;
593       case REF_SUBSTRING:
594         if (reference->u.ss.start != NULL)
595           offset += mpz_get_ui (*get_mpz (reference->u.ss.start)) - 1;
596         break;
597       default:
598         gfc_error ("Illegal reference type at %L as EQUIVALENCE object",
599                    &e->where);
600     }
601   return offset;
602 }
603
604
605 /* Add a new segment_info structure to the current segment.  eq1 is already
606    in the list, eq2 is not.  */
607
608 static void
609 new_condition (segment_info *v, gfc_equiv *eq1, gfc_equiv *eq2)
610 {
611   HOST_WIDE_INT offset1, offset2;
612   segment_info *a;
613
614   offset1 = calculate_offset (eq1->expr);
615   offset2 = calculate_offset (eq2->expr);
616
617   a = get_segment_info (eq2->expr->symtree->n.sym,
618                         v->offset + offset1 - offset2);
619  
620   current_segment = add_segments (current_segment, a);
621 }
622
623
624 /* Given two equivalence structures that are both already in the list, make
625    sure that this new condition is not violated, generating an error if it
626    is.  */
627
628 static void
629 confirm_condition (segment_info *s1, gfc_equiv *eq1, segment_info *s2,
630                    gfc_equiv *eq2)
631 {
632   HOST_WIDE_INT offset1, offset2;
633
634   offset1 = calculate_offset (eq1->expr);
635   offset2 = calculate_offset (eq2->expr);
636
637   if (s1->offset + offset1 != s2->offset + offset2)
638     gfc_error ("Inconsistent equivalence rules involving '%s' at %L and "
639                "'%s' at %L", s1->sym->name, &s1->sym->declared_at,
640                s2->sym->name, &s2->sym->declared_at);
641 }
642
643
644 /* Process a new equivalence condition. eq1 is know to be in segment f.
645    If eq2 is also present then confirm that the condition holds.
646    Otherwise add a new variable to the segment list.  */
647
648 static void
649 add_condition (segment_info *f, gfc_equiv *eq1, gfc_equiv *eq2)
650 {
651   segment_info *n;
652
653   n = find_segment_info (eq2->expr->symtree->n.sym);
654
655   if (n == NULL)
656     new_condition (f, eq1, eq2);
657   else
658     confirm_condition (f, eq1, n, eq2);
659 }
660
661
662 /* Given a segment element, search through the equivalence lists for unused
663    conditions that involve the symbol.  Add these rules to the segment.  Only
664    checks for rules involving the first symbol in the equivalence set.  */
665  
666 static bool
667 find_equivalence (segment_info *n)
668 {
669   gfc_equiv *e1, *e2, *eq, *other;
670   bool found;
671  
672   found = FALSE;
673   for (e1 = n->sym->ns->equiv; e1; e1 = e1->next)
674     {
675       other = NULL;
676       for (e2 = e1->eq; e2; e2 = e2->eq)
677         {
678           if (e2->used)
679             continue;
680
681           if (e1->expr->symtree->n.sym == n->sym)
682             {
683               eq = e1;
684               other = e2;
685             }
686           else if (e2->expr->symtree->n.sym == n->sym)
687             {
688               eq = e2;
689               other = e1;
690             }
691           else
692             eq = NULL;
693           
694           if (eq)
695             {
696               add_condition (n, eq, other);
697               eq->used = 1;
698               found = TRUE;
699               /* If this symbol is the first in the chain we may find other
700                  matches. Otherwise we can skip to the next equivalence.  */
701               if (eq == e2)
702                 break;
703             }
704         }
705     }
706   return found;
707 }
708
709
710 /* Add all symbols equivalenced within a segment.  We need to scan the
711    segment list multiple times to include indirect equivalences.  */
712
713 static void
714 add_equivalences (bool *saw_equiv)
715 {
716   segment_info *f;
717   bool more;
718
719   more = TRUE;
720   while (more)
721     {
722       more = FALSE;
723       for (f = current_segment; f; f = f->next)
724         {
725           if (!f->sym->equiv_built)
726             {
727               f->sym->equiv_built = 1;
728               more = find_equivalence (f);
729               if (more)
730                 *saw_equiv = true;
731             }
732         }
733     }
734 }
735
736
737 /* Returns the offset necessary to properly align the current equivalence.
738    Sets *palign to the required alignment.  */
739
740 static HOST_WIDE_INT
741 align_segment (unsigned HOST_WIDE_INT * palign)
742 {
743   segment_info *s;
744   unsigned HOST_WIDE_INT offset;
745   unsigned HOST_WIDE_INT max_align;
746   unsigned HOST_WIDE_INT this_align;
747   unsigned HOST_WIDE_INT this_offset;
748
749   max_align = 1;
750   offset = 0;
751   for (s = current_segment; s; s = s->next)
752     {
753       this_align = TYPE_ALIGN_UNIT (s->field);
754       if (s->offset & (this_align - 1))
755         {
756           /* Field is misaligned.  */
757           this_offset = this_align - ((s->offset + offset) & (this_align - 1));
758           if (this_offset & (max_align - 1))
759             {
760               /* Aligning this field would misalign a previous field.  */
761               gfc_error ("The equivalence set for variable '%s' "
762                          "declared at %L violates alignment requirents",
763                          s->sym->name, &s->sym->declared_at);
764             }
765           offset += this_offset;
766         }
767       max_align = this_align;
768     }
769   if (palign)
770     *palign = max_align;
771   return offset;
772 }
773
774
775 /* Adjust segment offsets by the given amount.  */
776
777 static void
778 apply_segment_offset (segment_info * s, HOST_WIDE_INT offset)
779 {
780   for (; s; s = s->next)
781     s->offset += offset;
782 }
783
784
785 /* Lay out a symbol in a common block.  If the symbol has already been seen
786    then check the location is consistent.  Otherwise create segments
787    for that symbol and all the symbols equivalenced with it.  */
788
789 /* Translate a single common block.  */
790
791 static void
792 translate_common (gfc_common_head *common, gfc_symbol *var_list)
793 {
794   gfc_symbol *sym;
795   segment_info *s;
796   segment_info *common_segment;
797   HOST_WIDE_INT offset;
798   HOST_WIDE_INT current_offset;
799   unsigned HOST_WIDE_INT align;
800   unsigned HOST_WIDE_INT max_align;
801   bool saw_equiv;
802
803   common_segment = NULL;
804   current_offset = 0;
805   max_align = 1;
806   saw_equiv = false;
807
808   /* Add symbols to the segment.  */
809   for (sym = var_list; sym; sym = sym->common_next)
810     {
811       if (sym->equiv_built)
812         {
813           /* Symbol has already been added via an equivalence.  */
814           current_segment = common_segment;
815           s = find_segment_info (sym);
816
817           /* Ensure the current location is properly aligned.  */
818           align = TYPE_ALIGN_UNIT (s->field);
819           current_offset = (current_offset + align - 1) &~ (align - 1);
820
821           /* Verify that it ended up where we expect it.  */
822           if (s->offset != current_offset)
823             {
824               gfc_error ("Equivalence for '%s' does not match ordering of "
825                          "COMMON '%s' at %L", sym->name,
826                          common->name, &common->where);
827             }
828         }
829       else
830         {
831           /* A symbol we haven't seen before.  */
832           s = current_segment = get_segment_info (sym, current_offset);
833
834           /* Add all objects directly or indirectly equivalenced with this
835              symbol.  */
836           add_equivalences (&saw_equiv);
837
838           if (current_segment->offset < 0)
839             gfc_error ("The equivalence set for '%s' cause an invalid "
840                        "extension to COMMON '%s' at %L", sym->name,
841                        common->name, &common->where);
842
843           offset = align_segment (&align);
844
845           if (offset & (max_align - 1))
846             {
847               /* The required offset conflicts with previous alignment
848                  requirements.  Insert padding immediately before this
849                  segment.  */
850               gfc_warning ("Padding of %d bytes required before '%s' in "
851                            "COMMON '%s' at %L", (int)offset, s->sym->name,
852                            common->name, &common->where);
853             }
854           else
855             {
856               /* Offset the whole common block.  */
857               apply_segment_offset (common_segment, offset);
858             }
859
860           /* Apply the offset to the new segments.  */
861           apply_segment_offset (current_segment, offset);
862           current_offset += offset;
863           if (max_align < align)
864             max_align = align;
865
866           /* Add the new segments to the common block.  */
867           common_segment = add_segments (common_segment, current_segment);
868         }
869
870       /* The offset of the next common variable.  */
871       current_offset += s->length;
872     }
873
874   if (common_segment->offset != 0)
875     {
876       gfc_warning ("COMMON '%s' at %L requires %d bytes of padding at start",
877                    common->name, &common->where, (int)common_segment->offset);
878     }
879
880   create_common (common, common_segment, saw_equiv);
881 }
882
883
884 /* Create a new block for each merged equivalence list.  */
885
886 static void
887 finish_equivalences (gfc_namespace *ns)
888 {
889   gfc_equiv *z, *y;
890   gfc_symbol *sym;
891   HOST_WIDE_INT offset;
892   unsigned HOST_WIDE_INT align;
893   bool dummy;
894
895   for (z = ns->equiv; z; z = z->next)
896     for (y = z->eq; y; y = y->eq)
897       {
898         if (y->used) 
899           continue;
900         sym = z->expr->symtree->n.sym;
901         current_segment = get_segment_info (sym, 0);
902
903         /* All objects directly or indirectly equivalenced with this symbol.  */
904         add_equivalences (&dummy);
905
906         /* Align the block.  */
907         offset = align_segment (&align);
908
909         /* Ensure all offsets are positive.  */
910         offset -= current_segment->offset & ~(align - 1);
911
912         apply_segment_offset (current_segment, offset);
913
914         /* Create the decl.  */
915         create_common (NULL, current_segment, true);
916         break;
917       }
918 }
919
920
921 /* Work function for translating a named common block.  */
922
923 static void
924 named_common (gfc_symtree *st)
925 {
926   translate_common (st->n.common, st->n.common->head);
927 }
928
929
930 /* Translate the common blocks in a namespace. Unlike other variables,
931    these have to be created before code, because the backend_decl depends
932    on the rest of the common block.  */
933
934 void
935 gfc_trans_common (gfc_namespace *ns)
936 {
937   gfc_common_head *c;
938
939   /* Translate the blank common block.  */
940   if (ns->blank_common.head != NULL)
941     {
942       c = gfc_get_common_head ();
943       /* We've lost the real location, so use the location of the
944          enclosing procedure.  */
945       c->where = ns->proc_name->declared_at;
946       strcpy (c->name, BLANK_COMMON_NAME);
947       translate_common (c, ns->blank_common.head);
948     }
949  
950   /* Translate all named common blocks.  */
951   gfc_traverse_symtree (ns->common_root, named_common);
952
953   /* Commit the newly created symbols for common blocks.  */
954   gfc_commit_symbols ();
955
956   /* Translate local equivalence.  */
957   finish_equivalences (ns);
958 }