OSDN Git Service

* dependency.c (gfc_check_dependency): Remove unused vars and nvars
[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 an 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 /* Make a segment_info based on a symbol.  */
123
124 static segment_info *
125 get_segment_info (gfc_symbol * sym, HOST_WIDE_INT offset)
126 {
127   segment_info *s;
128
129   /* Make sure we've got the character length.  */
130   if (sym->ts.type == BT_CHARACTER)
131     gfc_conv_const_charlen (sym->ts.cl);
132
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;
140
141   return s;
142 }
143
144 /* Add combine segment V and segment LIST.  */
145
146 static segment_info *
147 add_segments (segment_info *list, segment_info *v)
148 {
149   segment_info *s;
150   segment_info *p;
151   segment_info *next;
152
153   p = NULL;
154   s = list;
155
156   while (v)
157     {
158       /* Find the location of the new element.  */
159       while (s)
160         {
161           if (v->offset < s->offset)
162             break;
163           if (v->offset == s->offset
164               && v->length <= s->length)
165             break;
166
167           p = s;
168           s = s->next;
169         }
170
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;
178
179       p = v;
180       v = next;
181     }
182
183   return list;
184 }
185
186 /* Construct mangled common block name from symbol name.  */
187
188 static tree
189 gfc_sym_mangled_common_id (const char  *name)
190 {
191   int has_underscore;
192   char mangled_name[GFC_MAX_MANGLED_SYMBOL_LEN + 1];
193
194   if (strcmp (name, BLANK_COMMON_NAME) == 0)
195     return get_identifier (name);
196
197   if (gfc_option.flag_underscoring)
198     {
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);
204
205       return get_identifier (mangled_name);
206     }
207   else
208     return get_identifier (name);
209 }
210
211
212 /* Build a field declaration for a common variable or a local equivalence
213    object.  */
214
215 static void
216 build_field (segment_info *h, tree union_type, record_layout_info rli)
217 {
218   tree field;
219   tree name;
220   HOST_WIDE_INT offset = h->offset;
221   unsigned HOST_WIDE_INT desired_align, known_align;
222
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;
229
230   desired_align = update_alignment_for_field (rli, field, known_align);
231   if (desired_align > known_align)
232     DECL_PACKED (field) = 1;
233
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);
238
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)
247     {
248       tree len;
249       tree addr;
250
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);
262     }
263
264   h->field = field;
265 }
266
267
268 /* Get storage for local equivalence.  */
269
270 static tree
271 build_equiv_decl (tree union_type, bool is_init, bool is_saved)
272 {
273   tree decl;
274   char name[15];
275   static int serial = 0;
276
277   if (is_init)
278     {
279       decl = gfc_create_var (union_type, "equiv");
280       TREE_STATIC (decl) = 1;
281       return decl;
282     }
283
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;
288
289   if (!gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl))
290       || is_saved)
291     TREE_STATIC (decl) = 1;
292
293   TREE_ADDRESSABLE (decl) = 1;
294   TREE_USED (decl) = 1;
295
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);
299
300   gfc_add_decl_to_function (decl);
301
302   return decl;
303 }
304
305
306 /* Get storage for common block.  */
307
308 static tree
309 build_common_decl (gfc_common_head *com, tree union_type, bool is_init)
310 {
311   gfc_symbol *common_sym;
312   tree decl;
313
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);
317
318   gfc_get_symbol (com->name, gfc_common_ns, &common_sym);
319   decl = common_sym->backend_decl;
320
321   /* Update the size of this common block as needed.  */
322   if (decl != NULL_TREE)
323     {
324       tree size = TYPE_SIZE_UNIT (union_type);
325       if (tree_int_cst_lt (DECL_SIZE_UNIT (decl), size))
326         {
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;
334         }
335      }
336
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;
342
343   /* If there is no backend_decl for the common block, build it.  */
344   if (decl == NULL_TREE)
345     {
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;
352
353       gfc_set_decl_location (decl, &com->where);
354
355       /* Place the back end declaration for this common block in
356          GLOBAL_BINDING_LEVEL.  */
357       common_sym->backend_decl = pushdecl_top_level (decl);
358     }
359
360   /* Has no initial values.  */
361   if (!is_init)
362     {
363       DECL_INITIAL (decl) = NULL_TREE;
364       DECL_COMMON (decl) = 1;
365       DECL_DEFER_OUTPUT (decl) = 1;
366     }
367   else
368     {
369       DECL_INITIAL (decl) = error_mark_node;
370       DECL_COMMON (decl) = 0;
371       DECL_DEFER_OUTPUT (decl) = 0;
372     }
373   return decl;
374 }
375
376
377 /* Declare memory for the common block or local equivalence, and create
378    backend declarations for all of the elements.  */
379
380 static void
381 create_common (gfc_common_head *com, segment_info * head, bool saw_equiv)
382 {
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;
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       /* Has SAVE attribute.  */
417       if (s->sym->attr.save)
418         is_saved = true;
419     }
420   finish_record_layout (rli, true);
421
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);
426
427   if (is_init)
428     {
429       tree ctor, tmp;
430       HOST_WIDE_INT offset = 0;
431       VEC(constructor_elt,gc) *v = NULL;
432
433       for (s = head; s; s = s->next)
434         {
435           if (s->sym->value)
436             {
437               if (s->offset < offset)
438                 {
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");
444                 }
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);
449
450               CONSTRUCTOR_APPEND_ELT (v, s->field, tmp);
451               offset = s->offset + s->length;
452             }
453         }
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;
460
461 #ifdef ENABLE_CHECKING
462       {
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);
467       }
468 #endif
469     }
470
471   /* Build component reference for each variable.  */
472   for (s = head; s; s = next_s)
473     {
474       tree var_decl;
475
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;
486
487       if (com)
488         var_decl = pushdecl_top_level (var_decl);
489       else
490         gfc_add_decl_to_function (var_decl);
491
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;
496
497       if (s->sym->attr.assign)
498         {
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);
503         }
504
505       s->sym->backend_decl = var_decl;
506
507       next_s = s->next;
508       gfc_free (s);
509     }
510 }
511
512
513 /* Given a symbol, find it in the current segment list. Returns NULL if
514    not found.  */
515
516 static segment_info *
517 find_segment_info (gfc_symbol *symbol)
518 {
519   segment_info *n;
520
521   for (n = current_segment; n; n = n->next)
522     {
523       if (n->sym == symbol)
524         return n;
525     }
526
527   return NULL;
528 }
529
530
531 /* Given an expression node, make sure it is a constant integer and return
532    the mpz_t value.  */
533
534 static mpz_t *
535 get_mpz (gfc_expr *e)
536 {
537
538   if (e->expr_type != EXPR_CONSTANT)
539     gfc_internal_error ("get_mpz(): Not an integer constant");
540
541   return &e->value.integer;
542 }
543
544
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.  */
549  
550 static HOST_WIDE_INT
551 element_number (gfc_array_ref *ar)
552 {
553   mpz_t multiplier, offset, extent, n;
554   gfc_array_spec *as;
555   HOST_WIDE_INT i, rank;
556
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);
563
564   for (i = 0; i < rank; i++)
565     { 
566       if (ar->dimen_type[i] != DIMEN_ELEMENT)
567         gfc_internal_error ("element_number(): Bad dimension type");
568
569       mpz_sub (n, *get_mpz (ar->start[i]), *get_mpz (as->lower[i]));
570  
571       mpz_mul (n, n, multiplier);
572       mpz_add (offset, offset, n);
573  
574       mpz_sub (extent, *get_mpz (as->upper[i]), *get_mpz (as->lower[i]));
575       mpz_add_ui (extent, extent, 1);
576  
577       if (mpz_sgn (extent) < 0)
578         mpz_set_ui (extent, 0);
579  
580       mpz_mul (multiplier, multiplier, extent);
581     } 
582  
583   i = mpz_get_ui (offset);
584  
585   mpz_clear (multiplier);
586   mpz_clear (offset);
587   mpz_clear (extent);
588   mpz_clear (n);
589  
590   return i;
591 }
592
593
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.  */
599
600 static HOST_WIDE_INT
601 calculate_offset (gfc_expr *e)
602 {
603   HOST_WIDE_INT n, element_size, offset;
604   gfc_typespec *element_type;
605   gfc_ref *reference;
606
607   offset = 0;
608   element_type = &e->symtree->n.sym->ts;
609
610   for (reference = e->ref; reference; reference = reference->next)
611     switch (reference->type)
612       {
613       case REF_ARRAY:
614         switch (reference->u.ar.type)
615           {
616           case AR_FULL:
617             break;
618
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;
627
628           default:
629             gfc_error ("Bad array reference at %L", &e->where);
630           }
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);
639     }
640   return offset;
641 }
642
643
644 /* Add a new segment_info structure to the current segment.  eq1 is already
645    in the list, eq2 is not.  */
646
647 static void
648 new_condition (segment_info *v, gfc_equiv *eq1, gfc_equiv *eq2)
649 {
650   HOST_WIDE_INT offset1, offset2;
651   segment_info *a;
652
653   offset1 = calculate_offset (eq1->expr);
654   offset2 = calculate_offset (eq2->expr);
655
656   a = get_segment_info (eq2->expr->symtree->n.sym,
657                         v->offset + offset1 - offset2);
658  
659   current_segment = add_segments (current_segment, a);
660 }
661
662
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.  */
666
667 static void
668 confirm_condition (segment_info *s1, gfc_equiv *eq1, segment_info *s2,
669                    gfc_equiv *eq2)
670 {
671   HOST_WIDE_INT offset1, offset2;
672
673   offset1 = calculate_offset (eq1->expr);
674   offset2 = calculate_offset (eq2->expr);
675
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);
680 }
681
682
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.  */
686
687 static void
688 add_condition (segment_info *f, gfc_equiv *eq1, gfc_equiv *eq2)
689 {
690   segment_info *n;
691
692   n = find_segment_info (eq2->expr->symtree->n.sym);
693
694   if (n == NULL)
695     new_condition (f, eq1, eq2);
696   else
697     confirm_condition (f, eq1, n, eq2);
698 }
699
700
701 /* Given a segment element, search through the equivalence lists for unused
702    conditions that involve the symbol.  Add these rules to the segment.  */
703
704 static bool
705 find_equivalence (segment_info *n)
706 {
707   gfc_equiv *e1, *e2, *eq;
708   bool found;
709
710   found = FALSE;
711
712   for (e1 = n->sym->ns->equiv; e1; e1 = e1->next)
713     {
714       eq = NULL;
715
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)
719         {
720           if (!e2->used && e2->expr->symtree->n.sym == n->sym)
721             {
722               eq = e2;
723               break;
724             }
725         }
726
727       /* Go to the next root element.  */
728       if (eq == NULL)
729         continue;
730
731       eq->used = 1;
732
733       /* Now traverse the equivalence list matching the offsets.  */
734       for (e2 = e1; e2; e2 = e2->eq)
735         {
736           if (!e2->used && e2 != eq)
737             {
738               add_condition (n, eq, e2);
739               e2->used = 1;
740               found = TRUE;
741             }
742         }
743     }
744   return found;
745 }
746
747
748 /* Add all symbols equivalenced within a segment.  We need to scan the
749    segment list multiple times to include indirect equivalences.  */
750
751 static void
752 add_equivalences (bool *saw_equiv)
753 {
754   segment_info *f;
755   bool more;
756
757   more = TRUE;
758   while (more)
759     {
760       more = FALSE;
761       for (f = current_segment; f; f = f->next)
762         {
763           if (!f->sym->equiv_built)
764             {
765               f->sym->equiv_built = 1;
766               more = find_equivalence (f);
767               if (more)
768                 *saw_equiv = true;
769             }
770         }
771     }
772 }
773
774
775 /* Returns the offset necessary to properly align the current equivalence.
776    Sets *palign to the required alignment.  */
777
778 static HOST_WIDE_INT
779 align_segment (unsigned HOST_WIDE_INT * palign)
780 {
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;
786
787   max_align = 1;
788   offset = 0;
789   for (s = current_segment; s; s = s->next)
790     {
791       this_align = TYPE_ALIGN_UNIT (s->field);
792       if (s->offset & (this_align - 1))
793         {
794           /* Field is misaligned.  */
795           this_offset = this_align - ((s->offset + offset) & (this_align - 1));
796           if (this_offset & (max_align - 1))
797             {
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);
802             }
803           offset += this_offset;
804         }
805       max_align = this_align;
806     }
807   if (palign)
808     *palign = max_align;
809   return offset;
810 }
811
812
813 /* Adjust segment offsets by the given amount.  */
814
815 static void
816 apply_segment_offset (segment_info * s, HOST_WIDE_INT offset)
817 {
818   for (; s; s = s->next)
819     s->offset += offset;
820 }
821
822
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.  */
826
827 /* Translate a single common block.  */
828
829 static void
830 translate_common (gfc_common_head *common, gfc_symbol *var_list)
831 {
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;
840
841   common_segment = NULL;
842   current_offset = 0;
843   max_align = 1;
844   saw_equiv = false;
845
846   /* Add symbols to the segment.  */
847   for (sym = var_list; sym; sym = sym->common_next)
848     {
849       current_segment = common_segment;
850       s = find_segment_info (sym);
851
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)
856         {
857           /* Ensure the current location is properly aligned.  */
858           align = TYPE_ALIGN_UNIT (s->field);
859           current_offset = (current_offset + align - 1) &~ (align - 1);
860
861           /* Verify that it ended up where we expect it.  */
862           if (s->offset != current_offset)
863             {
864               gfc_error ("Equivalence for '%s' does not match ordering of "
865                          "COMMON '%s' at %L", sym->name,
866                          common->name, &common->where);
867             }
868         }
869       else
870         {
871           /* A symbol we haven't seen before.  */
872           s = current_segment = get_segment_info (sym, current_offset);
873
874           /* Add all objects directly or indirectly equivalenced with this
875              symbol.  */
876           add_equivalences (&saw_equiv);
877
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);
882
883           offset = align_segment (&align);
884
885           if (offset & (max_align - 1))
886             {
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);
893             }
894           else
895             {
896               /* Offset the whole common block.  */
897               apply_segment_offset (common_segment, offset);
898             }
899
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;
905
906           /* Add the new segments to the common block.  */
907           common_segment = add_segments (common_segment, current_segment);
908         }
909
910       /* The offset of the next common variable.  */
911       current_offset += s->length;
912     }
913
914   if (common_segment->offset != 0)
915     {
916       gfc_warning ("COMMON '%s' at %L requires %d bytes of padding at start",
917                    common->name, &common->where, (int)common_segment->offset);
918     }
919
920   create_common (common, common_segment, saw_equiv);
921 }
922
923
924 /* Create a new block for each merged equivalence list.  */
925
926 static void
927 finish_equivalences (gfc_namespace *ns)
928 {
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;
935
936   for (z = ns->equiv; z; z = z->next)
937     for (y = z->eq; y; y = y->eq)
938       {
939         if (y->used) 
940           continue;
941         sym = z->expr->symtree->n.sym;
942         current_segment = get_segment_info (sym, 0);
943
944         /* All objects directly or indirectly equivalenced with this symbol.  */
945         add_equivalences (&dummy);
946
947         /* Align the block.  */
948         offset = align_segment (&align);
949
950         /* Ensure all offsets are positive.  */
951         offset -= current_segment->offset & ~(align - 1);
952
953         apply_segment_offset (current_segment, offset);
954
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)
961           {
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);
967           }
968         else
969           c = NULL;
970
971         create_common (c, current_segment, true);
972         break;
973       }
974 }
975
976
977 /* Work function for translating a named common block.  */
978
979 static void
980 named_common (gfc_symtree *st)
981 {
982   translate_common (st->n.common, st->n.common->head);
983 }
984
985
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.  */
989
990 void
991 gfc_trans_common (gfc_namespace *ns)
992 {
993   gfc_common_head *c;
994
995   /* Translate the blank common block.  */
996   if (ns->blank_common.head != NULL)
997     {
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);
1004     }
1005  
1006   /* Translate all named common blocks.  */
1007   gfc_traverse_symtree (ns->common_root, named_common);
1008
1009   /* Commit the newly created symbols for common blocks.  */
1010   gfc_commit_symbols ();
1011
1012   /* Translate local equivalence.  */
1013   finish_equivalences (ns);
1014 }