OSDN Git Service

2007-06-12 Paul Thomas <pault@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / fortran / trans-common.c
1 /* Common block and equivalence list handling
2    Copyright (C) 2000, 2003, 2004, 2005, 2006, 2007
3    Free Software Foundation, Inc.
4    Contributed by Canqun Yang <canqun@nudt.edu.cn>
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING.  If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA.  */     
22
23 /* The core algorithm is based on Andy Vaught's g95 tree.  Also the
24    way to build UNION_TYPE is borrowed from Richard Henderson.
25  
26    Transform common blocks.  An integral part of this is processing
27    equivalence variables.  Equivalenced variables that are not in a
28    common block end up in a private block of their own.
29
30    Each common block or local equivalence list is declared as a union.
31    Variables within the block are represented as a field within the
32    block with the proper offset. 
33  
34    So if two variables are equivalenced, they just point to a common
35    area in memory.
36  
37    Mathematically, laying out an equivalence block is equivalent to
38    solving a linear system of equations.  The matrix is usually a
39    sparse matrix in which each row contains all zero elements except
40    for a +1 and a -1, a sort of a generalized Vandermonde matrix.  The
41    matrix is usually block diagonal.  The system can be
42    overdetermined, underdetermined or have a unique solution.  If the
43    system is inconsistent, the program is not standard conforming.
44    The solution vector is integral, since all of the pivots are +1 or -1.
45  
46    How we lay out an equivalence block is a little less complicated.
47    In an equivalence list with n elements, there are n-1 conditions to
48    be satisfied.  The conditions partition the variables into what we
49    will call segments.  If A and B are equivalenced then A and B are
50    in the same segment.  If B and C are equivalenced as well, then A,
51    B and C are in a segment and so on.  Each segment is a block of
52    memory that has one or more variables equivalenced in some way.  A
53    common block is made up of a series of segments that are joined one
54    after the other.  In the linear system, a segment is a block
55    diagonal.
56  
57    To lay out a segment we first start with some variable and
58    determine its length.  The first variable is assumed to start at
59    offset one and extends to however long it is.  We then traverse the
60    list of equivalences to find an unused condition that involves at
61    least one of the variables currently in the segment.
62  
63    Each equivalence condition amounts to the condition B+b=C+c where B
64    and C are the offsets of the B and C variables, and b and c are
65    constants which are nonzero for array elements, substrings or
66    structure components.  So for
67  
68      EQUIVALENCE(B(2), C(3))
69    we have
70      B + 2*size of B's elements = C + 3*size of C's elements.
71  
72    If B and C are known we check to see if the condition already
73    holds.  If B is known we can solve for C.  Since we know the length
74    of C, we can see if the minimum and maximum extents of the segment
75    are affected.  Eventually, we make a full pass through the
76    equivalence list without finding any new conditions and the segment
77    is fully specified.
78  
79    At this point, the segment is added to the current common block.
80    Since we know the minimum extent of the segment, everything in the
81    segment is translated to its position in the common block.  The
82    usual case here is that there are no equivalence statements and the
83    common block is series of segments with one variable each, which is
84    a diagonal matrix in the matrix formulation.
85  
86    Each segment is described by a chain of segment_info structures.  Each
87    segment_info structure describes the extents of a single variable within
88    the segment.  This list is maintained in the order the elements are
89    positioned withing the segment.  If two elements have the same starting
90    offset the smaller will come first.  If they also have the same size their
91    ordering is undefined. 
92    
93    Once all common blocks have been created, the list of equivalences
94    is examined for still-unused equivalence conditions.  We create a
95    block for each merged equivalence list.  */
96
97 #include "config.h"
98 #include "system.h"
99 #include "coretypes.h"
100 #include "target.h"
101 #include "tree.h"
102 #include "toplev.h"
103 #include "tm.h"
104 #include "rtl.h"
105 #include "gfortran.h"
106 #include "trans.h"
107 #include "trans-types.h"
108 #include "trans-const.h"
109 #include "target-memory.h"
110
111
112 /* Holds a single variable in an equivalence set.  */
113 typedef struct segment_info
114 {
115   gfc_symbol *sym;
116   HOST_WIDE_INT offset;
117   HOST_WIDE_INT length;
118   /* This will contain the field type until the field is created.  */
119   tree field;
120   struct segment_info *next;
121 } segment_info;
122
123 static segment_info * current_segment;
124 static gfc_namespace *gfc_common_ns = NULL;
125
126
127 /* Make a segment_info based on a symbol.  */
128
129 static segment_info *
130 get_segment_info (gfc_symbol * sym, HOST_WIDE_INT offset)
131 {
132   segment_info *s;
133
134   /* Make sure we've got the character length.  */
135   if (sym->ts.type == BT_CHARACTER)
136     gfc_conv_const_charlen (sym->ts.cl);
137
138   /* Create the segment_info and fill it in.  */
139   s = (segment_info *) gfc_getmem (sizeof (segment_info));
140   s->sym = sym;
141   /* We will use this type when building the segment aggregate type.  */
142   s->field = gfc_sym_type (sym);
143   s->length = int_size_in_bytes (s->field);
144   s->offset = offset;
145
146   return s;
147 }
148
149
150 /* Add a copy of a segment list to the namespace.  This is specifically for
151    equivalence segments, so that dependency checking can be done on
152    equivalence group members.  */
153
154 static void
155 copy_equiv_list_to_ns (segment_info *c)
156 {
157   segment_info *f;
158   gfc_equiv_info *s;
159   gfc_equiv_list *l;
160
161   l = (gfc_equiv_list *) gfc_getmem (sizeof (gfc_equiv_list));
162
163   l->next = c->sym->ns->equiv_lists;
164   c->sym->ns->equiv_lists = l;
165
166   for (f = c; f; f = f->next)
167     {
168       s = (gfc_equiv_info *) gfc_getmem (sizeof (gfc_equiv_info));
169       s->next = l->equiv;
170       l->equiv = s;
171       s->sym = f->sym;
172       s->offset = f->offset;
173       s->length = f->length;
174     }
175 }
176
177
178 /* Add combine segment V and segment LIST.  */
179
180 static segment_info *
181 add_segments (segment_info *list, segment_info *v)
182 {
183   segment_info *s;
184   segment_info *p;
185   segment_info *next;
186
187   p = NULL;
188   s = list;
189
190   while (v)
191     {
192       /* Find the location of the new element.  */
193       while (s)
194         {
195           if (v->offset < s->offset)
196             break;
197           if (v->offset == s->offset
198               && v->length <= s->length)
199             break;
200
201           p = s;
202           s = s->next;
203         }
204
205       /* Insert the new element in between p and s.  */
206       next = v->next;
207       v->next = s;
208       if (p == NULL)
209         list = v;
210       else
211         p->next = v;
212
213       p = v;
214       v = next;
215     }
216
217   return list;
218 }
219
220 /* Construct mangled common block name from symbol name.  */
221
222 static tree
223 gfc_sym_mangled_common_id (const char *name)
224 {
225   int has_underscore;
226   char mangled_name[GFC_MAX_MANGLED_SYMBOL_LEN + 1];
227
228   if (strcmp (name, BLANK_COMMON_NAME) == 0)
229     return get_identifier (name);
230
231   if (gfc_option.flag_underscoring)
232     {
233       has_underscore = strchr (name, '_') != 0;
234       if (gfc_option.flag_second_underscore && has_underscore)
235         snprintf (mangled_name, sizeof mangled_name, "%s__", name);
236       else
237         snprintf (mangled_name, sizeof mangled_name, "%s_", name);
238
239       return get_identifier (mangled_name);
240     }
241   else
242     return get_identifier (name);
243 }
244
245
246 /* Build a field declaration for a common variable or a local equivalence
247    object.  */
248
249 static void
250 build_field (segment_info *h, tree union_type, record_layout_info rli)
251 {
252   tree field;
253   tree name;
254   HOST_WIDE_INT offset = h->offset;
255   unsigned HOST_WIDE_INT desired_align, known_align;
256
257   name = get_identifier (h->sym->name);
258   field = build_decl (FIELD_DECL, name, h->field);
259   gfc_set_decl_location (field, &h->sym->declared_at);
260   known_align = (offset & -offset) * BITS_PER_UNIT;
261   if (known_align == 0 || known_align > BIGGEST_ALIGNMENT)
262     known_align = BIGGEST_ALIGNMENT;
263
264   desired_align = update_alignment_for_field (rli, field, known_align);
265   if (desired_align > known_align)
266     DECL_PACKED (field) = 1;
267
268   DECL_FIELD_CONTEXT (field) = union_type;
269   DECL_FIELD_OFFSET (field) = size_int (offset);
270   DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
271   SET_DECL_OFFSET_ALIGN (field, known_align);
272
273   rli->offset = size_binop (MAX_EXPR, rli->offset,
274                             size_binop (PLUS_EXPR,
275                                         DECL_FIELD_OFFSET (field),
276                                         DECL_SIZE_UNIT (field)));
277   /* If this field is assigned to a label, we create another two variables.
278      One will hold the address of target label or format label. The other will
279      hold the length of format label string.  */
280   if (h->sym->attr.assign)
281     {
282       tree len;
283       tree addr;
284
285       gfc_allocate_lang_decl (field);
286       GFC_DECL_ASSIGN (field) = 1;
287       len = gfc_create_var_np (gfc_charlen_type_node,h->sym->name);
288       addr = gfc_create_var_np (pvoid_type_node, h->sym->name);
289       TREE_STATIC (len) = 1;
290       TREE_STATIC (addr) = 1;
291       DECL_INITIAL (len) = build_int_cst (NULL_TREE, -2);
292       gfc_set_decl_location (len, &h->sym->declared_at);
293       gfc_set_decl_location (addr, &h->sym->declared_at);
294       GFC_DECL_STRING_LEN (field) = pushdecl_top_level (len);
295       GFC_DECL_ASSIGN_ADDR (field) = pushdecl_top_level (addr);
296     }
297
298   h->field = field;
299 }
300
301
302 /* Get storage for local equivalence.  */
303
304 static tree
305 build_equiv_decl (tree union_type, bool is_init, bool is_saved)
306 {
307   tree decl;
308   char name[15];
309   static int serial = 0;
310
311   if (is_init)
312     {
313       decl = gfc_create_var (union_type, "equiv");
314       TREE_STATIC (decl) = 1;
315       GFC_DECL_COMMON_OR_EQUIV (decl) = 1;
316       return decl;
317     }
318
319   snprintf (name, sizeof (name), "equiv.%d", serial++);
320   decl = build_decl (VAR_DECL, get_identifier (name), union_type);
321   DECL_ARTIFICIAL (decl) = 1;
322   DECL_IGNORED_P (decl) = 1;
323
324   if (!gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl))
325       || is_saved)
326     TREE_STATIC (decl) = 1;
327
328   TREE_ADDRESSABLE (decl) = 1;
329   TREE_USED (decl) = 1;
330   GFC_DECL_COMMON_OR_EQUIV (decl) = 1;
331
332   /* The source location has been lost, and doesn't really matter.
333      We need to set it to something though.  */
334   gfc_set_decl_location (decl, &gfc_current_locus);
335
336   gfc_add_decl_to_function (decl);
337
338   return decl;
339 }
340
341
342 /* Get storage for common block.  */
343
344 static tree
345 build_common_decl (gfc_common_head *com, tree union_type, bool is_init)
346 {
347   gfc_symbol *common_sym;
348   tree decl;
349
350   /* Create a namespace to store symbols for common blocks.  */
351   if (gfc_common_ns == NULL)
352     gfc_common_ns = gfc_get_namespace (NULL, 0);
353
354   gfc_get_symbol (com->name, gfc_common_ns, &common_sym);
355   decl = common_sym->backend_decl;
356
357   /* Update the size of this common block as needed.  */
358   if (decl != NULL_TREE)
359     {
360       tree size = TYPE_SIZE_UNIT (union_type);
361       if (tree_int_cst_lt (DECL_SIZE_UNIT (decl), size))
362         {
363           /* Named common blocks of the same name shall be of the same size
364              in all scoping units of a program in which they appear, but
365              blank common blocks may be of different sizes.  */
366           if (strcmp (com->name, BLANK_COMMON_NAME))
367             gfc_warning ("Named COMMON block '%s' at %L shall be of the "
368                          "same size", com->name, &com->where);
369           DECL_SIZE_UNIT (decl) = size;
370         }
371      }
372
373   /* If this common block has been declared in a previous program unit,
374      and either it is already initialized or there is no new initialization
375      for it, just return.  */
376   if ((decl != NULL_TREE) && (!is_init || DECL_INITIAL (decl)))
377     return decl;
378
379   /* If there is no backend_decl for the common block, build it.  */
380   if (decl == NULL_TREE)
381     {
382       decl = build_decl (VAR_DECL, get_identifier (com->name), union_type);
383       SET_DECL_ASSEMBLER_NAME (decl, gfc_sym_mangled_common_id (com->name));
384       TREE_PUBLIC (decl) = 1;
385       TREE_STATIC (decl) = 1;
386       DECL_ALIGN (decl) = BIGGEST_ALIGNMENT;
387       DECL_USER_ALIGN (decl) = 0;
388       GFC_DECL_COMMON_OR_EQUIV (decl) = 1;
389
390       gfc_set_decl_location (decl, &com->where);
391
392       if (com->threadprivate)
393         DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
394
395       /* Place the back end declaration for this common block in
396          GLOBAL_BINDING_LEVEL.  */
397       common_sym->backend_decl = pushdecl_top_level (decl);
398     }
399
400   /* Has no initial values.  */
401   if (!is_init)
402     {
403       DECL_INITIAL (decl) = NULL_TREE;
404       DECL_COMMON (decl) = 1;
405       DECL_DEFER_OUTPUT (decl) = 1;
406     }
407   else
408     {
409       DECL_INITIAL (decl) = error_mark_node;
410       DECL_COMMON (decl) = 0;
411       DECL_DEFER_OUTPUT (decl) = 0;
412     }
413   return decl;
414 }
415
416
417 /* Return a field that is the size of the union, if an equivalence has
418    overlapping initializers.  Merge the initializers into a single
419    initializer for this new field, then free the old ones.  */ 
420
421 static tree
422 get_init_field (segment_info *head, tree union_type, tree *field_init,
423                 record_layout_info rli)
424 {
425   segment_info *s;
426   HOST_WIDE_INT length = 0;
427   HOST_WIDE_INT offset = 0;
428   unsigned HOST_WIDE_INT known_align, desired_align;
429   bool overlap = false;
430   tree tmp, field;
431   tree init;
432   unsigned char *data, *chk;
433   VEC(constructor_elt,gc) *v = NULL;
434
435   tree type = unsigned_char_type_node;
436   int i;
437
438   /* Obtain the size of the union and check if there are any overlapping
439      initializers.  */
440   for (s = head; s; s = s->next)
441     {
442       HOST_WIDE_INT slen = s->offset + s->length;
443       if (s->sym->value)
444         {
445           if (s->offset < offset)
446             overlap = true;
447           offset = slen;
448         }
449       length = length < slen ? slen : length;
450     }
451
452   if (!overlap)
453     return NULL_TREE;
454
455   /* Now absorb all the initializer data into a single vector,
456      whilst checking for overlapping, unequal values.  */
457   data = (unsigned char*)gfc_getmem ((size_t)length);
458   chk = (unsigned char*)gfc_getmem ((size_t)length);
459
460   /* TODO - change this when default initialization is implemented.  */
461   memset (data, '\0', (size_t)length);
462   memset (chk, '\0', (size_t)length);
463   for (s = head; s; s = s->next)
464     if (s->sym->value)
465       gfc_merge_initializers (s->sym->ts, s->sym->value,
466                               &data[s->offset],
467                               &chk[s->offset],
468                              (size_t)s->length);
469   
470   for (i = 0; i < length; i++)
471     CONSTRUCTOR_APPEND_ELT (v, NULL, build_int_cst (type, data[i]));
472
473   gfc_free (data);
474   gfc_free (chk);
475
476   /* Build a char[length] array to hold the initializers.  Much of what
477      follows is borrowed from build_field, above.  */
478
479   tmp = build_int_cst (gfc_array_index_type, length - 1);
480   tmp = build_range_type (gfc_array_index_type,
481                           gfc_index_zero_node, tmp);
482   tmp = build_array_type (type, tmp);
483   field = build_decl (FIELD_DECL, NULL_TREE, tmp);
484   gfc_set_decl_location (field, &gfc_current_locus);
485
486   known_align = BIGGEST_ALIGNMENT;
487
488   desired_align = update_alignment_for_field (rli, field, known_align);
489   if (desired_align > known_align)
490     DECL_PACKED (field) = 1;
491
492   DECL_FIELD_CONTEXT (field) = union_type;
493   DECL_FIELD_OFFSET (field) = size_int (0);
494   DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
495   SET_DECL_OFFSET_ALIGN (field, known_align);
496
497   rli->offset = size_binop (MAX_EXPR, rli->offset,
498                             size_binop (PLUS_EXPR,
499                                         DECL_FIELD_OFFSET (field),
500                                         DECL_SIZE_UNIT (field)));
501
502   init = build_constructor (TREE_TYPE (field), v);
503   TREE_CONSTANT (init) = 1;
504   TREE_INVARIANT (init) = 1;
505
506   *field_init = init;
507
508   for (s = head; s; s = s->next)
509     {
510       if (s->sym->value == NULL)
511         continue;
512
513       gfc_free_expr (s->sym->value);
514       s->sym->value = NULL;
515     }
516
517   return field;
518 }
519
520
521 /* Declare memory for the common block or local equivalence, and create
522    backend declarations for all of the elements.  */
523
524 static void
525 create_common (gfc_common_head *com, segment_info *head, bool saw_equiv)
526 {
527   segment_info *s, *next_s;
528   tree union_type;
529   tree *field_link;
530   tree field;
531   tree field_init;
532   record_layout_info rli;
533   tree decl;
534   bool is_init = false;
535   bool is_saved = false;
536
537   /* Declare the variables inside the common block.
538      If the current common block contains any equivalence object, then
539      make a UNION_TYPE node, otherwise RECORD_TYPE. This will let the
540      alias analyzer work well when there is no address overlapping for
541      common variables in the current common block.  */
542   if (saw_equiv)
543     union_type = make_node (UNION_TYPE);
544   else
545     union_type = make_node (RECORD_TYPE);
546
547   rli = start_record_layout (union_type);
548   field_link = &TYPE_FIELDS (union_type);
549
550   /* Check for overlapping initializers and replace them with a single,
551      artificial field that contains all the data.  */
552   if (saw_equiv)
553     field = get_init_field (head, union_type, &field_init, rli);
554   else
555     field = NULL_TREE;
556
557   if (field != NULL_TREE)
558     {
559       is_init = true;
560       *field_link = field;
561       field_link = &TREE_CHAIN (field);
562     }
563
564   for (s = head; s; s = s->next)
565     {
566       build_field (s, union_type, rli);
567
568       /* Link the field into the type.  */
569       *field_link = s->field;
570       field_link = &TREE_CHAIN (s->field);
571
572       /* Has initial value.  */
573       if (s->sym->value)
574         is_init = true;
575
576       /* Has SAVE attribute.  */
577       if (s->sym->attr.save)
578         is_saved = true;
579     }
580
581   finish_record_layout (rli, true);
582
583   if (com)
584     decl = build_common_decl (com, union_type, is_init);
585   else
586     decl = build_equiv_decl (union_type, is_init, is_saved);
587
588   if (is_init)
589     {
590       tree ctor, tmp;
591       HOST_WIDE_INT offset = 0;
592       VEC(constructor_elt,gc) *v = NULL;
593
594       if (field != NULL_TREE && field_init != NULL_TREE)
595         CONSTRUCTOR_APPEND_ELT (v, field, field_init);
596       else
597         for (s = head; s; s = s->next)
598           {
599             if (s->sym->value)
600               {
601                 /* Add the initializer for this field.  */
602                 tmp = gfc_conv_initializer (s->sym->value, &s->sym->ts,
603                     TREE_TYPE (s->field), s->sym->attr.dimension,
604                     s->sym->attr.pointer || s->sym->attr.allocatable);
605
606                 CONSTRUCTOR_APPEND_ELT (v, s->field, tmp);
607                 offset = s->offset + s->length;
608               }
609           }
610
611       gcc_assert (!VEC_empty (constructor_elt, v));
612       ctor = build_constructor (union_type, v);
613       TREE_CONSTANT (ctor) = 1;
614       TREE_INVARIANT (ctor) = 1;
615       TREE_STATIC (ctor) = 1;
616       DECL_INITIAL (decl) = ctor;
617
618 #ifdef ENABLE_CHECKING
619       {
620         tree field, value;
621         unsigned HOST_WIDE_INT idx;
622         FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, field, value)
623           gcc_assert (TREE_CODE (field) == FIELD_DECL);
624       }
625 #endif
626     }
627
628   /* Build component reference for each variable.  */
629   for (s = head; s; s = next_s)
630     {
631       tree var_decl;
632
633       var_decl = build_decl (VAR_DECL, DECL_NAME (s->field),
634                              TREE_TYPE (s->field));
635       gfc_set_decl_location (var_decl, &s->sym->declared_at);
636       TREE_PUBLIC (var_decl) = TREE_PUBLIC (decl);
637       TREE_STATIC (var_decl) = TREE_STATIC (decl);
638       TREE_USED (var_decl) = TREE_USED (decl);
639       if (s->sym->attr.target)
640         TREE_ADDRESSABLE (var_decl) = 1;
641       /* This is a fake variable just for debugging purposes.  */
642       TREE_ASM_WRITTEN (var_decl) = 1;
643
644       if (com)
645         var_decl = pushdecl_top_level (var_decl);
646       else
647         gfc_add_decl_to_function (var_decl);
648
649       SET_DECL_VALUE_EXPR (var_decl,
650                            build3 (COMPONENT_REF, TREE_TYPE (s->field),
651                                    decl, s->field, NULL_TREE));
652       DECL_HAS_VALUE_EXPR_P (var_decl) = 1;
653       GFC_DECL_COMMON_OR_EQUIV (var_decl) = 1;
654
655       if (s->sym->attr.assign)
656         {
657           gfc_allocate_lang_decl (var_decl);
658           GFC_DECL_ASSIGN (var_decl) = 1;
659           GFC_DECL_STRING_LEN (var_decl) = GFC_DECL_STRING_LEN (s->field);
660           GFC_DECL_ASSIGN_ADDR (var_decl) = GFC_DECL_ASSIGN_ADDR (s->field);
661         }
662
663       s->sym->backend_decl = var_decl;
664
665       next_s = s->next;
666       gfc_free (s);
667     }
668 }
669
670
671 /* Given a symbol, find it in the current segment list. Returns NULL if
672    not found.  */
673
674 static segment_info *
675 find_segment_info (gfc_symbol *symbol)
676 {
677   segment_info *n;
678
679   for (n = current_segment; n; n = n->next)
680     {
681       if (n->sym == symbol)
682         return n;
683     }
684
685   return NULL;
686 }
687
688
689 /* Given an expression node, make sure it is a constant integer and return
690    the mpz_t value.  */
691
692 static mpz_t *
693 get_mpz (gfc_expr *e)
694 {
695
696   if (e->expr_type != EXPR_CONSTANT)
697     gfc_internal_error ("get_mpz(): Not an integer constant");
698
699   return &e->value.integer;
700 }
701
702
703 /* Given an array specification and an array reference, figure out the
704    array element number (zero based). Bounds and elements are guaranteed
705    to be constants.  If something goes wrong we generate an error and
706    return zero.  */
707  
708 static HOST_WIDE_INT
709 element_number (gfc_array_ref *ar)
710 {
711   mpz_t multiplier, offset, extent, n;
712   gfc_array_spec *as;
713   HOST_WIDE_INT i, rank;
714
715   as = ar->as;
716   rank = as->rank;
717   mpz_init_set_ui (multiplier, 1);
718   mpz_init_set_ui (offset, 0);
719   mpz_init (extent);
720   mpz_init (n);
721
722   for (i = 0; i < rank; i++)
723     { 
724       if (ar->dimen_type[i] != DIMEN_ELEMENT)
725         gfc_internal_error ("element_number(): Bad dimension type");
726
727       mpz_sub (n, *get_mpz (ar->start[i]), *get_mpz (as->lower[i]));
728  
729       mpz_mul (n, n, multiplier);
730       mpz_add (offset, offset, n);
731  
732       mpz_sub (extent, *get_mpz (as->upper[i]), *get_mpz (as->lower[i]));
733       mpz_add_ui (extent, extent, 1);
734  
735       if (mpz_sgn (extent) < 0)
736         mpz_set_ui (extent, 0);
737  
738       mpz_mul (multiplier, multiplier, extent);
739     } 
740  
741   i = mpz_get_ui (offset);
742  
743   mpz_clear (multiplier);
744   mpz_clear (offset);
745   mpz_clear (extent);
746   mpz_clear (n);
747  
748   return i;
749 }
750
751
752 /* Given a single element of an equivalence list, figure out the offset
753    from the base symbol.  For simple variables or full arrays, this is
754    simply zero.  For an array element we have to calculate the array
755    element number and multiply by the element size. For a substring we
756    have to calculate the further reference.  */
757
758 static HOST_WIDE_INT
759 calculate_offset (gfc_expr *e)
760 {
761   HOST_WIDE_INT n, element_size, offset;
762   gfc_typespec *element_type;
763   gfc_ref *reference;
764
765   offset = 0;
766   element_type = &e->symtree->n.sym->ts;
767
768   for (reference = e->ref; reference; reference = reference->next)
769     switch (reference->type)
770       {
771       case REF_ARRAY:
772         switch (reference->u.ar.type)
773           {
774           case AR_FULL:
775             break;
776
777           case AR_ELEMENT:
778             n = element_number (&reference->u.ar);
779             if (element_type->type == BT_CHARACTER)
780               gfc_conv_const_charlen (element_type->cl);
781             element_size =
782               int_size_in_bytes (gfc_typenode_for_spec (element_type));
783             offset += n * element_size;
784             break;
785
786           default:
787             gfc_error ("Bad array reference at %L", &e->where);
788           }
789         break;
790       case REF_SUBSTRING:
791         if (reference->u.ss.start != NULL)
792           offset += mpz_get_ui (*get_mpz (reference->u.ss.start)) - 1;
793         break;
794       default:
795         gfc_error ("Illegal reference type at %L as EQUIVALENCE object",
796                    &e->where);
797     }
798   return offset;
799 }
800
801
802 /* Add a new segment_info structure to the current segment.  eq1 is already
803    in the list, eq2 is not.  */
804
805 static void
806 new_condition (segment_info *v, gfc_equiv *eq1, gfc_equiv *eq2)
807 {
808   HOST_WIDE_INT offset1, offset2;
809   segment_info *a;
810
811   offset1 = calculate_offset (eq1->expr);
812   offset2 = calculate_offset (eq2->expr);
813
814   a = get_segment_info (eq2->expr->symtree->n.sym,
815                         v->offset + offset1 - offset2);
816  
817   current_segment = add_segments (current_segment, a);
818 }
819
820
821 /* Given two equivalence structures that are both already in the list, make
822    sure that this new condition is not violated, generating an error if it
823    is.  */
824
825 static void
826 confirm_condition (segment_info *s1, gfc_equiv *eq1, segment_info *s2,
827                    gfc_equiv *eq2)
828 {
829   HOST_WIDE_INT offset1, offset2;
830
831   offset1 = calculate_offset (eq1->expr);
832   offset2 = calculate_offset (eq2->expr);
833
834   if (s1->offset + offset1 != s2->offset + offset2)
835     gfc_error ("Inconsistent equivalence rules involving '%s' at %L and "
836                "'%s' at %L", s1->sym->name, &s1->sym->declared_at,
837                s2->sym->name, &s2->sym->declared_at);
838 }
839
840
841 /* Process a new equivalence condition. eq1 is know to be in segment f.
842    If eq2 is also present then confirm that the condition holds.
843    Otherwise add a new variable to the segment list.  */
844
845 static void
846 add_condition (segment_info *f, gfc_equiv *eq1, gfc_equiv *eq2)
847 {
848   segment_info *n;
849
850   n = find_segment_info (eq2->expr->symtree->n.sym);
851
852   if (n == NULL)
853     new_condition (f, eq1, eq2);
854   else
855     confirm_condition (f, eq1, n, eq2);
856 }
857
858
859 /* Given a segment element, search through the equivalence lists for unused
860    conditions that involve the symbol.  Add these rules to the segment.  */
861
862 static bool
863 find_equivalence (segment_info *n)
864 {
865   gfc_equiv *e1, *e2, *eq;
866   bool found;
867
868   found = FALSE;
869
870   for (e1 = n->sym->ns->equiv; e1; e1 = e1->next)
871     {
872       eq = NULL;
873
874       /* Search the equivalence list, including the root (first) element
875          for the symbol that owns the segment.  */
876       for (e2 = e1; e2; e2 = e2->eq)
877         {
878           if (!e2->used && e2->expr->symtree->n.sym == n->sym)
879             {
880               eq = e2;
881               break;
882             }
883         }
884
885       /* Go to the next root element.  */
886       if (eq == NULL)
887         continue;
888
889       eq->used = 1;
890
891       /* Now traverse the equivalence list matching the offsets.  */
892       for (e2 = e1; e2; e2 = e2->eq)
893         {
894           if (!e2->used && e2 != eq)
895             {
896               add_condition (n, eq, e2);
897               e2->used = 1;
898               found = TRUE;
899             }
900         }
901     }
902   return found;
903 }
904
905
906 /* Add all symbols equivalenced within a segment.  We need to scan the
907    segment list multiple times to include indirect equivalences.  Since
908    a new segment_info can inserted at the beginning of the segment list,
909    depending on its offset, we have to force a final pass through the
910    loop by demanding that completion sees a pass with no matches; ie.
911    all symbols with equiv_built set and no new equivalences found.  */
912
913 static void
914 add_equivalences (bool *saw_equiv)
915 {
916   segment_info *f;
917   bool seen_one, more;
918
919   seen_one = false;
920   more = TRUE;
921   while (more)
922     {
923       more = FALSE;
924       for (f = current_segment; f; f = f->next)
925         {
926           if (!f->sym->equiv_built)
927             {
928               f->sym->equiv_built = 1;
929               seen_one = find_equivalence (f);
930               if (seen_one)
931                 {
932                   *saw_equiv = true;
933                   more = true;
934                 }
935             }
936         }
937     }
938
939   /* Add a copy of this segment list to the namespace.  */
940   copy_equiv_list_to_ns (current_segment);
941 }
942
943
944 /* Returns the offset necessary to properly align the current equivalence.
945    Sets *palign to the required alignment.  */
946
947 static HOST_WIDE_INT
948 align_segment (unsigned HOST_WIDE_INT *palign)
949 {
950   segment_info *s;
951   unsigned HOST_WIDE_INT offset;
952   unsigned HOST_WIDE_INT max_align;
953   unsigned HOST_WIDE_INT this_align;
954   unsigned HOST_WIDE_INT this_offset;
955
956   max_align = 1;
957   offset = 0;
958   for (s = current_segment; s; s = s->next)
959     {
960       this_align = TYPE_ALIGN_UNIT (s->field);
961       if (s->offset & (this_align - 1))
962         {
963           /* Field is misaligned.  */
964           this_offset = this_align - ((s->offset + offset) & (this_align - 1));
965           if (this_offset & (max_align - 1))
966             {
967               /* Aligning this field would misalign a previous field.  */
968               gfc_error ("The equivalence set for variable '%s' "
969                          "declared at %L violates alignment requirements",
970                          s->sym->name, &s->sym->declared_at);
971             }
972           offset += this_offset;
973         }
974       max_align = this_align;
975     }
976   if (palign)
977     *palign = max_align;
978   return offset;
979 }
980
981
982 /* Adjust segment offsets by the given amount.  */
983
984 static void
985 apply_segment_offset (segment_info *s, HOST_WIDE_INT offset)
986 {
987   for (; s; s = s->next)
988     s->offset += offset;
989 }
990
991
992 /* Lay out a symbol in a common block.  If the symbol has already been seen
993    then check the location is consistent.  Otherwise create segments
994    for that symbol and all the symbols equivalenced with it.  */
995
996 /* Translate a single common block.  */
997
998 static void
999 translate_common (gfc_common_head *common, gfc_symbol *var_list)
1000 {
1001   gfc_symbol *sym;
1002   segment_info *s;
1003   segment_info *common_segment;
1004   HOST_WIDE_INT offset;
1005   HOST_WIDE_INT current_offset;
1006   unsigned HOST_WIDE_INT align;
1007   unsigned HOST_WIDE_INT max_align;
1008   bool saw_equiv;
1009
1010   common_segment = NULL;
1011   current_offset = 0;
1012   max_align = 1;
1013   saw_equiv = false;
1014
1015   /* Add symbols to the segment.  */
1016   for (sym = var_list; sym; sym = sym->common_next)
1017     {
1018       current_segment = common_segment;
1019       s = find_segment_info (sym);
1020
1021       /* Symbol has already been added via an equivalence.  Multiple
1022          use associations of the same common block result in equiv_built
1023          being set but no information about the symbol in the segment.  */
1024       if (s && sym->equiv_built)
1025         {
1026           /* Ensure the current location is properly aligned.  */
1027           align = TYPE_ALIGN_UNIT (s->field);
1028           current_offset = (current_offset + align - 1) &~ (align - 1);
1029
1030           /* Verify that it ended up where we expect it.  */
1031           if (s->offset != current_offset)
1032             {
1033               gfc_error ("Equivalence for '%s' does not match ordering of "
1034                          "COMMON '%s' at %L", sym->name,
1035                          common->name, &common->where);
1036             }
1037         }
1038       else
1039         {
1040           /* A symbol we haven't seen before.  */
1041           s = current_segment = get_segment_info (sym, current_offset);
1042
1043           /* Add all objects directly or indirectly equivalenced with this
1044              symbol.  */
1045           add_equivalences (&saw_equiv);
1046
1047           if (current_segment->offset < 0)
1048             gfc_error ("The equivalence set for '%s' cause an invalid "
1049                        "extension to COMMON '%s' at %L", sym->name,
1050                        common->name, &common->where);
1051
1052           offset = align_segment (&align);
1053
1054           if (offset & (max_align - 1))
1055             {
1056               /* The required offset conflicts with previous alignment
1057                  requirements.  Insert padding immediately before this
1058                  segment.  */
1059               gfc_warning ("Padding of %d bytes required before '%s' in "
1060                            "COMMON '%s' at %L", (int)offset, s->sym->name,
1061                            common->name, &common->where);
1062             }
1063           else
1064             {
1065               /* Offset the whole common block.  */
1066               apply_segment_offset (common_segment, offset);
1067             }
1068
1069           /* Apply the offset to the new segments.  */
1070           apply_segment_offset (current_segment, offset);
1071           current_offset += offset;
1072           if (max_align < align)
1073             max_align = align;
1074
1075           /* Add the new segments to the common block.  */
1076           common_segment = add_segments (common_segment, current_segment);
1077         }
1078
1079       /* The offset of the next common variable.  */
1080       current_offset += s->length;
1081     }
1082
1083   if (common_segment == NULL)
1084     {
1085       gfc_error ("COMMON '%s' at %L does not exist",
1086                  common->name, &common->where);
1087       return;
1088     }
1089
1090   if (common_segment->offset != 0)
1091     {
1092       gfc_warning ("COMMON '%s' at %L requires %d bytes of padding at start",
1093                    common->name, &common->where, (int)common_segment->offset);
1094     }
1095
1096   create_common (common, common_segment, saw_equiv);
1097 }
1098
1099
1100 /* Create a new block for each merged equivalence list.  */
1101
1102 static void
1103 finish_equivalences (gfc_namespace *ns)
1104 {
1105   gfc_equiv *z, *y;
1106   gfc_symbol *sym;
1107   gfc_common_head * c;
1108   HOST_WIDE_INT offset;
1109   unsigned HOST_WIDE_INT align;
1110   bool dummy;
1111
1112   for (z = ns->equiv; z; z = z->next)
1113     for (y = z->eq; y; y = y->eq)
1114       {
1115         if (y->used) 
1116           continue;
1117         sym = z->expr->symtree->n.sym;
1118         current_segment = get_segment_info (sym, 0);
1119
1120         /* All objects directly or indirectly equivalenced with this
1121            symbol.  */
1122         add_equivalences (&dummy);
1123
1124         /* Align the block.  */
1125         offset = align_segment (&align);
1126
1127         /* Ensure all offsets are positive.  */
1128         offset -= current_segment->offset & ~(align - 1);
1129
1130         apply_segment_offset (current_segment, offset);
1131
1132         /* Create the decl.  If this is a module equivalence, it has a
1133            unique name, pointed to by z->module.  This is written to a
1134            gfc_common_header to push create_common into using
1135            build_common_decl, so that the equivalence appears as an
1136            external symbol.  Otherwise, a local declaration is built using
1137            build_equiv_decl.  */
1138         if (z->module)
1139           {
1140             c = gfc_get_common_head ();
1141             /* We've lost the real location, so use the location of the
1142                enclosing procedure.  */
1143             c->where = ns->proc_name->declared_at;
1144             strcpy (c->name, z->module);
1145           }
1146         else
1147           c = NULL;
1148
1149         create_common (c, current_segment, true);
1150         break;
1151       }
1152 }
1153
1154
1155 /* Work function for translating a named common block.  */
1156
1157 static void
1158 named_common (gfc_symtree *st)
1159 {
1160   translate_common (st->n.common, st->n.common->head);
1161 }
1162
1163
1164 /* Translate the common blocks in a namespace. Unlike other variables,
1165    these have to be created before code, because the backend_decl depends
1166    on the rest of the common block.  */
1167
1168 void
1169 gfc_trans_common (gfc_namespace *ns)
1170 {
1171   gfc_common_head *c;
1172
1173   /* Translate the blank common block.  */
1174   if (ns->blank_common.head != NULL)
1175     {
1176       c = gfc_get_common_head ();
1177
1178       /* We've lost the real location, so use the location of the
1179          enclosing procedure.  */
1180       if (ns->proc_name != NULL)
1181         c->where = ns->proc_name->declared_at;
1182       else
1183         c->where = ns->blank_common.head->common_head->where;
1184
1185       strcpy (c->name, BLANK_COMMON_NAME);
1186       translate_common (c, ns->blank_common.head);
1187     }
1188
1189   /* Translate all named common blocks.  */
1190   gfc_traverse_symtree (ns->common_root, named_common);
1191
1192   /* Translate local equivalence.  */
1193   finish_equivalences (ns);
1194
1195   /* Commit the newly created symbols for common blocks and module
1196      equivalences.  */
1197   gfc_commit_symbols ();
1198 }