1 /* Data flow functions for trees.
2 Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3 Contributed by Diego Novillo <dnovillo@redhat.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to
19 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
24 #include "coretypes.h"
27 #include "pointer-set.h"
31 #include "hard-reg-set.h"
32 #include "basic-block.h"
37 #include "langhooks.h"
40 #include "diagnostic.h"
41 #include "tree-dump.h"
42 #include "tree-gimple.h"
43 #include "tree-flow.h"
44 #include "tree-inline.h"
45 #include "tree-pass.h"
50 /* Build and maintain data flow information for trees. */
52 /* Counters used to display DFA and SSA statistics. */
67 /* Local functions. */
68 static void collect_dfa_stats (struct dfa_stats_d *);
69 static tree collect_dfa_stats_r (tree *, int *, void *);
70 static tree find_vars_r (tree *, int *, void *);
73 /*---------------------------------------------------------------------------
74 Dataflow analysis (DFA) routines
75 ---------------------------------------------------------------------------*/
76 /* Find all the variables referenced in the function. This function
77 builds the global arrays REFERENCED_VARS and CALL_CLOBBERED_VARS.
79 Note that this function does not look for statement operands, it simply
80 determines what variables are referenced in the program and detects
81 various attributes for each variable used by alias analysis and the
85 find_referenced_vars (void)
88 block_stmt_iterator si;
91 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
93 tree *stmt_p = bsi_stmt_ptr (si);
94 walk_tree (stmt_p, find_vars_r, NULL, NULL);
100 struct tree_opt_pass pass_referenced_vars =
104 find_referenced_vars, /* execute */
107 0, /* static_pass_number */
108 TV_FIND_REFERENCED_VARS, /* tv_id */
109 PROP_gimple_leh | PROP_cfg, /* properties_required */
110 PROP_referenced_vars, /* properties_provided */
111 0, /* properties_destroyed */
112 0, /* todo_flags_start */
113 0, /* todo_flags_finish */
118 /*---------------------------------------------------------------------------
120 ---------------------------------------------------------------------------*/
121 /* Create a new annotation for a _DECL node T. */
124 create_var_ann (tree t)
129 gcc_assert (DECL_P (t));
130 gcc_assert (!t->base.ann || t->base.ann->common.type == VAR_ANN);
132 ann = GGC_CNEW (struct var_ann_d);
134 ann->common.type = VAR_ANN;
136 t->base.ann = (tree_ann_t) ann;
141 /* Create a new annotation for a FUNCTION_DECL node T. */
144 create_function_ann (tree t)
149 gcc_assert (TREE_CODE (t) == FUNCTION_DECL);
150 gcc_assert (!t->base.ann || t->base.ann->common.type == FUNCTION_ANN);
152 ann = ggc_alloc (sizeof (*ann));
153 memset ((void *) ann, 0, sizeof (*ann));
155 ann->common.type = FUNCTION_ANN;
157 t->base.ann = (tree_ann_t) ann;
162 /* Create a new annotation for a statement node T. */
165 create_stmt_ann (tree t)
169 gcc_assert (is_gimple_stmt (t));
170 gcc_assert (!t->base.ann || t->base.ann->common.type == STMT_ANN);
172 ann = GGC_CNEW (struct stmt_ann_d);
174 ann->common.type = STMT_ANN;
176 /* Since we just created the annotation, mark the statement modified. */
177 ann->modified = true;
179 t->base.ann = (tree_ann_t) ann;
184 /* Create a new annotation for a tree T. */
187 create_tree_common_ann (tree t)
189 tree_ann_common_t ann;
192 gcc_assert (!t->base.ann || t->base.ann->common.type == TREE_ANN_COMMON);
194 ann = GGC_CNEW (struct tree_ann_common_d);
196 ann->type = TREE_ANN_COMMON;
197 t->base.ann = (tree_ann_t) ann;
202 /* Build a temporary. Make sure and register it to be renamed. */
205 make_rename_temp (tree type, const char *prefix)
207 tree t = create_tmp_var (type, prefix);
209 if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
210 || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
211 DECL_GIMPLE_REG_P (t) = 1;
213 if (gimple_referenced_vars (cfun))
215 add_referenced_var (t);
216 mark_sym_for_renaming (t);
224 /*---------------------------------------------------------------------------
226 ---------------------------------------------------------------------------*/
227 /* Dump the list of all the referenced variables in the current function to
231 dump_referenced_vars (FILE *file)
234 referenced_var_iterator rvi;
236 fprintf (file, "\nReferenced variables in %s: %u\n\n",
237 get_name (current_function_decl), (unsigned) num_referenced_vars);
239 FOR_EACH_REFERENCED_VAR (var, rvi)
241 fprintf (file, "Variable: ");
242 dump_variable (file, var);
243 fprintf (file, "\n");
248 /* Dump the list of all the referenced variables to stderr. */
251 debug_referenced_vars (void)
253 dump_referenced_vars (stderr);
257 /* Dump sub-variables for VAR to FILE. */
260 dump_subvars_for (FILE *file, tree var)
262 subvar_t sv = get_subvars_for_var (var);
267 fprintf (file, "{ ");
269 for (; sv; sv = sv->next)
271 print_generic_expr (file, sv->var, dump_flags);
279 /* Dumb sub-variables for VAR to stderr. */
282 debug_subvars_for (tree var)
284 dump_subvars_for (stderr, var);
288 /* Dump variable VAR and its may-aliases to FILE. */
291 dump_variable (FILE *file, tree var)
295 if (TREE_CODE (var) == SSA_NAME)
297 if (POINTER_TYPE_P (TREE_TYPE (var)))
298 dump_points_to_info_for (file, var);
299 var = SSA_NAME_VAR (var);
302 if (var == NULL_TREE)
304 fprintf (file, "<nil>");
308 print_generic_expr (file, var, dump_flags);
312 fprintf (file, ", UID %u", (unsigned) DECL_UID (var));
314 fprintf (file, ", ");
315 print_generic_expr (file, TREE_TYPE (var), dump_flags);
317 if (ann && ann->symbol_mem_tag)
319 fprintf (file, ", symbol memory tag: ");
320 print_generic_expr (file, ann->symbol_mem_tag, dump_flags);
323 if (ann && ann->is_aliased)
324 fprintf (file, ", is aliased");
326 if (TREE_ADDRESSABLE (var))
327 fprintf (file, ", is addressable");
329 if (is_global_var (var))
330 fprintf (file, ", is global");
332 if (TREE_THIS_VOLATILE (var))
333 fprintf (file, ", is volatile");
335 if (is_call_clobbered (var))
337 var_ann_t va = var_ann (var);
338 unsigned int escape_mask = va->escape_mask;
340 fprintf (file, ", call clobbered");
341 fprintf (file, " (");
342 if (escape_mask & ESCAPE_STORED_IN_GLOBAL)
343 fprintf (file, ", stored in global");
344 if (escape_mask & ESCAPE_TO_ASM)
345 fprintf (file, ", goes through ASM");
346 if (escape_mask & ESCAPE_TO_CALL)
347 fprintf (file, ", passed to call");
348 if (escape_mask & ESCAPE_BAD_CAST)
349 fprintf (file, ", bad cast");
350 if (escape_mask & ESCAPE_TO_RETURN)
351 fprintf (file, ", returned from func");
352 if (escape_mask & ESCAPE_TO_PURE_CONST)
353 fprintf (file, ", passed to pure/const");
354 if (escape_mask & ESCAPE_IS_GLOBAL)
355 fprintf (file, ", is global var");
356 if (escape_mask & ESCAPE_IS_PARM)
357 fprintf (file, ", is incoming pointer");
358 if (escape_mask & ESCAPE_UNKNOWN)
359 fprintf (file, ", unknown escape");
360 fprintf (file, " )");
363 if (gimple_default_def (cfun, var))
365 fprintf (file, ", default def: ");
366 print_generic_expr (file, gimple_default_def (cfun, var), dump_flags);
369 if (may_aliases (var))
371 fprintf (file, ", may aliases: ");
372 dump_may_aliases_for (file, var);
375 if (get_subvars_for_var (var))
377 fprintf (file, ", sub-vars: ");
378 dump_subvars_for (file, var);
381 if (!is_gimple_reg (var))
383 if (memory_partition (var))
385 fprintf (file, ", belongs to partition: ");
386 print_generic_expr (file, memory_partition (var), dump_flags);
389 if (TREE_CODE (var) == MEMORY_PARTITION_TAG)
391 fprintf (file, ", partition symbols: ");
392 dump_decl_set (file, MPT_SYMBOLS (var));
396 fprintf (file, "\n");
400 /* Dump variable VAR and its may-aliases to stderr. */
403 debug_variable (tree var)
405 dump_variable (stderr, var);
409 /* Dump various DFA statistics to FILE. */
412 dump_dfa_stats (FILE *file)
414 struct dfa_stats_d dfa_stats;
416 unsigned long size, total = 0;
417 const char * const fmt_str = "%-30s%-13s%12s\n";
418 const char * const fmt_str_1 = "%-30s%13lu%11lu%c\n";
419 const char * const fmt_str_3 = "%-43s%11lu%c\n";
421 = lang_hooks.decl_printable_name (current_function_decl, 2);
423 collect_dfa_stats (&dfa_stats);
425 fprintf (file, "\nDFA Statistics for %s\n\n", funcname);
427 fprintf (file, "---------------------------------------------------------\n");
428 fprintf (file, fmt_str, "", " Number of ", "Memory");
429 fprintf (file, fmt_str, "", " instances ", "used ");
430 fprintf (file, "---------------------------------------------------------\n");
432 size = num_referenced_vars * sizeof (tree);
434 fprintf (file, fmt_str_1, "Referenced variables", (unsigned long)num_referenced_vars,
435 SCALE (size), LABEL (size));
437 size = dfa_stats.num_stmt_anns * sizeof (struct stmt_ann_d);
439 fprintf (file, fmt_str_1, "Statements annotated", dfa_stats.num_stmt_anns,
440 SCALE (size), LABEL (size));
442 size = dfa_stats.num_var_anns * sizeof (struct var_ann_d);
444 fprintf (file, fmt_str_1, "Variables annotated", dfa_stats.num_var_anns,
445 SCALE (size), LABEL (size));
447 size = dfa_stats.num_uses * sizeof (tree *);
449 fprintf (file, fmt_str_1, "USE operands", dfa_stats.num_uses,
450 SCALE (size), LABEL (size));
452 size = dfa_stats.num_defs * sizeof (tree *);
454 fprintf (file, fmt_str_1, "DEF operands", dfa_stats.num_defs,
455 SCALE (size), LABEL (size));
457 size = dfa_stats.num_vuses * sizeof (tree *);
459 fprintf (file, fmt_str_1, "VUSE operands", dfa_stats.num_vuses,
460 SCALE (size), LABEL (size));
462 size = dfa_stats.num_vdefs * sizeof (tree *);
464 fprintf (file, fmt_str_1, "VDEF operands", dfa_stats.num_vdefs,
465 SCALE (size), LABEL (size));
467 size = dfa_stats.num_phis * sizeof (struct tree_phi_node);
469 fprintf (file, fmt_str_1, "PHI nodes", dfa_stats.num_phis,
470 SCALE (size), LABEL (size));
472 size = dfa_stats.num_phi_args * sizeof (struct phi_arg_d);
474 fprintf (file, fmt_str_1, "PHI arguments", dfa_stats.num_phi_args,
475 SCALE (size), LABEL (size));
477 fprintf (file, "---------------------------------------------------------\n");
478 fprintf (file, fmt_str_3, "Total memory used by DFA/SSA data", SCALE (total),
480 fprintf (file, "---------------------------------------------------------\n");
481 fprintf (file, "\n");
483 if (dfa_stats.num_phis)
484 fprintf (file, "Average number of arguments per PHI node: %.1f (max: %d)\n",
485 (float) dfa_stats.num_phi_args / (float) dfa_stats.num_phis,
486 dfa_stats.max_num_phi_args);
488 fprintf (file, "\n");
492 /* Dump DFA statistics on stderr. */
495 debug_dfa_stats (void)
497 dump_dfa_stats (stderr);
501 /* Collect DFA statistics and store them in the structure pointed to by
505 collect_dfa_stats (struct dfa_stats_d *dfa_stats_p)
507 struct pointer_set_t *pset;
509 block_stmt_iterator i;
511 gcc_assert (dfa_stats_p);
513 memset ((void *)dfa_stats_p, 0, sizeof (struct dfa_stats_d));
515 /* Walk all the trees in the function counting references. Start at
516 basic block NUM_FIXED_BLOCKS, but don't stop at block boundaries. */
517 pset = pointer_set_create ();
519 for (i = bsi_start (BASIC_BLOCK (NUM_FIXED_BLOCKS));
520 !bsi_end_p (i); bsi_next (&i))
521 walk_tree (bsi_stmt_ptr (i), collect_dfa_stats_r, (void *) dfa_stats_p,
524 pointer_set_destroy (pset);
529 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
531 dfa_stats_p->num_phis++;
532 dfa_stats_p->num_phi_args += PHI_NUM_ARGS (phi);
533 if (PHI_NUM_ARGS (phi) > dfa_stats_p->max_num_phi_args)
534 dfa_stats_p->max_num_phi_args = PHI_NUM_ARGS (phi);
540 /* Callback for walk_tree to collect DFA statistics for a tree and its
544 collect_dfa_stats_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
548 struct dfa_stats_d *dfa_stats_p = (struct dfa_stats_d *)data;
552 switch (ann_type (t->base.ann))
556 dfa_stats_p->num_stmt_anns++;
557 dfa_stats_p->num_defs += NUM_SSA_OPERANDS (t, SSA_OP_DEF);
558 dfa_stats_p->num_uses += NUM_SSA_OPERANDS (t, SSA_OP_USE);
559 dfa_stats_p->num_vdefs += NUM_SSA_OPERANDS (t, SSA_OP_VDEF);
560 dfa_stats_p->num_vuses += NUM_SSA_OPERANDS (t, SSA_OP_VUSE);
565 dfa_stats_p->num_var_anns++;
577 /*---------------------------------------------------------------------------
578 Miscellaneous helpers
579 ---------------------------------------------------------------------------*/
580 /* Callback for walk_tree. Used to collect variables referenced in
584 find_vars_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
586 /* If T is a regular variable that the optimizers are interested
587 in, add it to the list of variables. */
589 add_referenced_var (*tp);
591 /* Type, _DECL and constant nodes have no interesting children.
593 else if (IS_TYPE_OR_DECL_P (*tp) || CONSTANT_CLASS_P (*tp))
599 /* Lookup UID in the referenced_vars hashtable and return the associated
603 referenced_var_lookup (unsigned int uid)
605 struct int_tree_map *h, in;
607 h = (struct int_tree_map *) htab_find_with_hash (gimple_referenced_vars (cfun),
609 gcc_assert (h || uid == 0);
615 /* Check if TO is in the referenced_vars hash table and insert it if not.
616 Return true if it required insertion. */
619 referenced_var_check_and_insert (tree to)
621 struct int_tree_map *h, in;
623 unsigned int uid = DECL_UID (to);
627 h = (struct int_tree_map *) htab_find_with_hash (gimple_referenced_vars (cfun),
632 /* DECL_UID has already been entered in the table. Verify that it is
633 the same entry as TO. See PR 27793. */
634 gcc_assert (h->to == to);
638 h = GGC_NEW (struct int_tree_map);
641 loc = htab_find_slot_with_hash (gimple_referenced_vars (cfun),
643 *(struct int_tree_map **) loc = h;
647 /* Lookup VAR UID in the default_defs hashtable and return the associated
651 gimple_default_def (struct function *fn, tree var)
653 struct int_tree_map *h, in;
654 gcc_assert (SSA_VAR_P (var));
655 in.uid = DECL_UID (var);
656 h = (struct int_tree_map *) htab_find_with_hash (DEFAULT_DEFS (fn),
664 /* Insert the pair VAR's UID, DEF into the default_defs hashtable. */
667 set_default_def (tree var, tree def)
669 struct int_tree_map in;
670 struct int_tree_map *h;
673 gcc_assert (SSA_VAR_P (var));
674 in.uid = DECL_UID (var);
675 if (!def && gimple_default_def (cfun, var))
677 loc = htab_find_slot_with_hash (DEFAULT_DEFS (cfun), &in,
678 DECL_UID (var), INSERT);
679 htab_remove_elt (DEFAULT_DEFS (cfun), *loc);
682 gcc_assert (TREE_CODE (def) == SSA_NAME);
683 loc = htab_find_slot_with_hash (DEFAULT_DEFS (cfun), &in,
684 DECL_UID (var), INSERT);
686 /* Default definition might be changed by tail call optimization. */
689 h = GGC_NEW (struct int_tree_map);
690 h->uid = DECL_UID (var);
692 *(struct int_tree_map **) loc = h;
696 h = (struct int_tree_map *) *loc;
697 SSA_NAME_IS_DEFAULT_DEF (h->to) = false;
701 /* Mark DEF as the default definition for VAR. */
702 SSA_NAME_IS_DEFAULT_DEF (def) = true;
705 /* Add VAR to the list of referenced variables if it isn't already there. */
708 add_referenced_var (tree var)
712 v_ann = get_var_ann (var);
713 gcc_assert (DECL_P (var));
715 /* Insert VAR into the referenced_vars has table if it isn't present. */
716 if (referenced_var_check_and_insert (var))
718 /* This is the first time we found this variable, annotate it with
719 attributes that are intrinsic to the variable. */
721 /* Tag's don't have DECL_INITIAL. */
725 /* Scan DECL_INITIAL for pointer variables as they may contain
726 address arithmetic referencing the address of other
728 if (DECL_INITIAL (var)
729 /* Initializers of external variables are not useful to the
731 && !DECL_EXTERNAL (var)
732 /* It's not necessary to walk the initial value of non-constant
733 variables because it cannot be propagated by the
735 && (TREE_CONSTANT (var) || TREE_READONLY (var)))
736 walk_tree (&DECL_INITIAL (var), find_vars_r, NULL, 0);
741 /* Return the virtual variable associated to the non-scalar variable VAR. */
744 get_virtual_var (tree var)
748 if (TREE_CODE (var) == SSA_NAME)
749 var = SSA_NAME_VAR (var);
751 while (TREE_CODE (var) == REALPART_EXPR || TREE_CODE (var) == IMAGPART_EXPR
752 || handled_component_p (var))
753 var = TREE_OPERAND (var, 0);
755 /* Treating GIMPLE registers as virtual variables makes no sense.
756 Also complain if we couldn't extract a _DECL out of the original
758 gcc_assert (SSA_VAR_P (var));
759 gcc_assert (!is_gimple_reg (var));
764 /* Mark all the naked symbols in STMT for SSA renaming.
766 NOTE: This function should only be used for brand new statements.
767 If the caller is modifying an existing statement, it should use the
768 combination push_stmt_changes/pop_stmt_changes. */
771 mark_symbols_for_renaming (tree stmt)
778 /* Mark all the operands for renaming. */
779 FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_ALL_OPERANDS)
781 mark_sym_for_renaming (op);
785 /* Find all variables within the gimplified statement that were not previously
786 visible to the function and add them to the referenced variables list. */
789 find_new_referenced_vars_1 (tree *tp, int *walk_subtrees,
790 void *data ATTRIBUTE_UNUSED)
794 if (TREE_CODE (t) == VAR_DECL && !var_ann (t))
796 add_referenced_var (t);
797 mark_sym_for_renaming (t);
800 if (IS_TYPE_OR_DECL_P (t))
807 find_new_referenced_vars (tree *stmt_p)
809 walk_tree (stmt_p, find_new_referenced_vars_1, NULL, NULL);
813 /* If EXP is a handled component reference for a structure, return the
814 base variable. The access range is delimited by bit positions *POFFSET and
815 *POFFSET + *PMAX_SIZE. The access size is *PSIZE bits. If either
816 *PSIZE or *PMAX_SIZE is -1, they could not be determined. If *PSIZE
817 and *PMAX_SIZE are equal, the access is non-variable. */
820 get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
821 HOST_WIDE_INT *psize,
822 HOST_WIDE_INT *pmax_size)
824 HOST_WIDE_INT bitsize = -1;
825 HOST_WIDE_INT maxsize = -1;
826 tree size_tree = NULL_TREE;
827 tree bit_offset = bitsize_zero_node;
828 bool seen_variable_array_ref = false;
830 gcc_assert (!SSA_VAR_P (exp));
832 /* First get the final access size from just the outermost expression. */
833 if (TREE_CODE (exp) == COMPONENT_REF)
834 size_tree = DECL_SIZE (TREE_OPERAND (exp, 1));
835 else if (TREE_CODE (exp) == BIT_FIELD_REF)
836 size_tree = TREE_OPERAND (exp, 1);
839 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
841 size_tree = TYPE_SIZE (TREE_TYPE (exp));
843 bitsize = GET_MODE_BITSIZE (mode);
845 if (size_tree != NULL_TREE)
847 if (! host_integerp (size_tree, 1))
850 bitsize = TREE_INT_CST_LOW (size_tree);
853 /* Initially, maxsize is the same as the accessed element size.
854 In the following it will only grow (or become -1). */
857 /* Compute cumulative bit-offset for nested component-refs and array-refs,
858 and find the ultimate containing object. */
861 switch (TREE_CODE (exp))
864 bit_offset = size_binop (PLUS_EXPR, bit_offset,
865 TREE_OPERAND (exp, 2));
870 tree field = TREE_OPERAND (exp, 1);
871 tree this_offset = component_ref_field_offset (exp);
873 if (this_offset && TREE_CODE (this_offset) == INTEGER_CST)
875 this_offset = size_binop (MULT_EXPR,
876 fold_convert (bitsizetype,
879 bit_offset = size_binop (PLUS_EXPR,
880 bit_offset, this_offset);
881 bit_offset = size_binop (PLUS_EXPR, bit_offset,
882 DECL_FIELD_BIT_OFFSET (field));
886 tree csize = TYPE_SIZE (TREE_TYPE (TREE_OPERAND (exp, 0)));
887 /* We need to adjust maxsize to the whole structure bitsize.
888 But we can subtract any constant offset seen sofar,
889 because that would get us out of the structure otherwise. */
891 && csize && host_integerp (csize, 1))
893 maxsize = (TREE_INT_CST_LOW (csize)
894 - TREE_INT_CST_LOW (bit_offset));
903 case ARRAY_RANGE_REF:
905 tree index = TREE_OPERAND (exp, 1);
906 tree low_bound = array_ref_low_bound (exp);
907 tree unit_size = array_ref_element_size (exp);
909 if (! integer_zerop (low_bound))
910 index = fold_build2 (MINUS_EXPR, TREE_TYPE (index),
912 index = size_binop (MULT_EXPR,
913 fold_convert (sizetype, index), unit_size);
914 if (TREE_CODE (index) == INTEGER_CST)
916 index = size_binop (MULT_EXPR,
917 fold_convert (bitsizetype, index),
919 bit_offset = size_binop (PLUS_EXPR, bit_offset, index);
921 /* An array ref with a constant index up in the structure
922 hierarchy will constrain the size of any variable array ref
923 lower in the access hierarchy. */
924 seen_variable_array_ref = false;
928 tree asize = TYPE_SIZE (TREE_TYPE (TREE_OPERAND (exp, 0)));
929 /* We need to adjust maxsize to the whole array bitsize.
930 But we can subtract any constant offset seen sofar,
931 because that would get us outside of the array otherwise. */
933 && asize && host_integerp (asize, 1))
935 maxsize = (TREE_INT_CST_LOW (asize)
936 - TREE_INT_CST_LOW (bit_offset));
941 /* Remember that we have seen an array ref with a variable
943 seen_variable_array_ref = true;
952 bit_offset = size_binop (PLUS_EXPR, bit_offset,
953 bitsize_int (bitsize));
956 case VIEW_CONVERT_EXPR:
957 /* ??? We probably should give up here and bail out. */
964 exp = TREE_OPERAND (exp, 0);
968 /* We need to deal with variable arrays ending structures such as
969 struct { int length; int a[1]; } x; x.a[d]
970 struct { struct { int a; int b; } a[1]; } x; x.a[d].a
971 struct { struct { int a[1]; } a[1]; } x; x.a[0][d], x.a[d][0]
972 where we do not know maxsize for variable index accesses to
973 the array. The simplest way to conservatively deal with this
974 is to punt in the case that offset + maxsize reaches the
975 base type boundary. */
976 if (seen_variable_array_ref
978 && host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
979 && TREE_INT_CST_LOW (bit_offset) + maxsize
980 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))))
983 /* ??? Due to negative offsets in ARRAY_REF we can end up with
984 negative bit_offset here. We might want to store a zero offset
986 *poffset = TREE_INT_CST_LOW (bit_offset);
988 *pmax_size = maxsize;