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