1 /* Data flow functions for trees.
2 Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007 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 3, 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 COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
26 #include "pointer-set.h"
30 #include "hard-reg-set.h"
31 #include "basic-block.h"
36 #include "langhooks.h"
39 #include "diagnostic.h"
40 #include "tree-dump.h"
41 #include "tree-gimple.h"
42 #include "tree-flow.h"
43 #include "tree-inline.h"
44 #include "tree-pass.h"
49 /* Build and maintain data flow information for trees. */
51 /* 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 /* Global declarations. */
75 /* Array of all variables referenced in the function. */
76 htab_t referenced_vars
;
78 /* Default definition for this symbols. If set for symbol, it
79 means that the first reference to this variable in the function is a
80 USE or a VUSE. In those cases, the SSA renamer creates an SSA name
81 for this variable with an empty defining statement. */
85 /*---------------------------------------------------------------------------
86 Dataflow analysis (DFA) routines
87 ---------------------------------------------------------------------------*/
88 /* Find all the variables referenced in the function. This function
89 builds the global arrays REFERENCED_VARS and CALL_CLOBBERED_VARS.
91 Note that this function does not look for statement operands, it simply
92 determines what variables are referenced in the program and detects
93 various attributes for each variable used by alias analysis and the
97 find_referenced_vars (void)
100 block_stmt_iterator si
;
103 for (si
= bsi_start (bb
); !bsi_end_p (si
); bsi_next (&si
))
105 tree
*stmt_p
= bsi_stmt_ptr (si
);
106 walk_tree (stmt_p
, find_vars_r
, NULL
, NULL
);
112 struct tree_opt_pass pass_referenced_vars
=
116 find_referenced_vars
, /* execute */
119 0, /* static_pass_number */
120 TV_FIND_REFERENCED_VARS
, /* tv_id */
121 PROP_gimple_leh
| PROP_cfg
, /* properties_required */
122 PROP_referenced_vars
, /* properties_provided */
123 0, /* properties_destroyed */
124 0, /* todo_flags_start */
125 0, /* todo_flags_finish */
130 /*---------------------------------------------------------------------------
132 ---------------------------------------------------------------------------*/
133 /* Create a new annotation for a _DECL node T. */
136 create_var_ann (tree t
)
141 gcc_assert (DECL_P (t
));
142 gcc_assert (!t
->common
.ann
|| t
->common
.ann
->common
.type
== VAR_ANN
);
144 ann
= GGC_CNEW (struct var_ann_d
);
146 ann
->common
.type
= VAR_ANN
;
148 t
->common
.ann
= (tree_ann_t
) ann
;
153 /* Create a new annotation for a FUNCTION_DECL node T. */
156 create_function_ann (tree t
)
161 gcc_assert (TREE_CODE (t
) == FUNCTION_DECL
);
162 gcc_assert (!t
->common
.ann
|| t
->common
.ann
->common
.type
== FUNCTION_ANN
);
164 ann
= ggc_alloc (sizeof (*ann
));
165 memset ((void *) ann
, 0, sizeof (*ann
));
167 ann
->common
.type
= FUNCTION_ANN
;
169 t
->common
.ann
= (tree_ann_t
) ann
;
174 /* Create a new annotation for a statement node T. */
177 create_stmt_ann (tree t
)
181 gcc_assert (is_gimple_stmt (t
));
182 gcc_assert (!t
->common
.ann
|| t
->common
.ann
->common
.type
== STMT_ANN
);
184 ann
= GGC_CNEW (struct stmt_ann_d
);
186 ann
->common
.type
= STMT_ANN
;
188 /* Since we just created the annotation, mark the statement modified. */
189 ann
->modified
= true;
191 t
->common
.ann
= (tree_ann_t
) ann
;
196 /* Create a new annotation for a tree T. */
199 create_tree_common_ann (tree t
)
201 tree_ann_common_t ann
;
204 gcc_assert (!t
->common
.ann
|| t
->common
.ann
->common
.type
== TREE_ANN_COMMON
);
206 ann
= GGC_CNEW (struct tree_ann_common_d
);
208 ann
->type
= TREE_ANN_COMMON
;
209 t
->common
.ann
= (tree_ann_t
) ann
;
214 /* Build a temporary. Make sure and register it to be renamed. */
217 make_rename_temp (tree type
, const char *prefix
)
219 tree t
= create_tmp_var (type
, prefix
);
221 if (TREE_CODE (type
) == COMPLEX_TYPE
)
222 DECL_COMPLEX_GIMPLE_REG_P (t
) = 1;
226 add_referenced_var (t
);
227 mark_sym_for_renaming (t
);
235 /*---------------------------------------------------------------------------
237 ---------------------------------------------------------------------------*/
238 /* Dump the list of all the referenced variables in the current function to
242 dump_referenced_vars (FILE *file
)
245 referenced_var_iterator rvi
;
247 fprintf (file
, "\nReferenced variables in %s: %u\n\n",
248 get_name (current_function_decl
), (unsigned) num_referenced_vars
);
250 FOR_EACH_REFERENCED_VAR (var
, rvi
)
252 fprintf (file
, "Variable: ");
253 dump_variable (file
, var
);
254 fprintf (file
, "\n");
259 /* Dump the list of all the referenced variables to stderr. */
262 debug_referenced_vars (void)
264 dump_referenced_vars (stderr
);
268 /* Dump sub-variables for VAR to FILE. */
271 dump_subvars_for (FILE *file
, tree var
)
273 subvar_t sv
= get_subvars_for_var (var
);
278 fprintf (file
, "{ ");
280 for (; sv
; sv
= sv
->next
)
282 print_generic_expr (file
, sv
->var
, dump_flags
);
290 /* Dumb sub-variables for VAR to stderr. */
293 debug_subvars_for (tree var
)
295 dump_subvars_for (stderr
, var
);
299 /* Dump variable VAR and its may-aliases to FILE. */
302 dump_variable (FILE *file
, tree var
)
306 if (TREE_CODE (var
) == SSA_NAME
)
308 if (POINTER_TYPE_P (TREE_TYPE (var
)))
309 dump_points_to_info_for (file
, var
);
310 var
= SSA_NAME_VAR (var
);
313 if (var
== NULL_TREE
)
315 fprintf (file
, "<nil>");
319 print_generic_expr (file
, var
, dump_flags
);
323 fprintf (file
, ", UID %u", (unsigned) DECL_UID (var
));
325 fprintf (file
, ", ");
326 print_generic_expr (file
, TREE_TYPE (var
), dump_flags
);
328 if (ann
&& ann
->symbol_mem_tag
)
330 fprintf (file
, ", symbol memory tag: ");
331 print_generic_expr (file
, ann
->symbol_mem_tag
, dump_flags
);
334 if (ann
&& ann
->is_aliased
)
335 fprintf (file
, ", is aliased");
337 if (TREE_ADDRESSABLE (var
))
338 fprintf (file
, ", is addressable");
340 if (is_global_var (var
))
341 fprintf (file
, ", is global");
343 if (TREE_THIS_VOLATILE (var
))
344 fprintf (file
, ", is volatile");
346 if (is_call_clobbered (var
))
348 fprintf (file
, ", call clobbered");
349 if (dump_flags
& TDF_DETAILS
)
351 var_ann_t va
= var_ann (var
);
352 unsigned int escape_mask
= va
->escape_mask
;
354 fprintf (file
, " (");
355 if (escape_mask
& ESCAPE_STORED_IN_GLOBAL
)
356 fprintf (file
, ", stored in global");
357 if (escape_mask
& ESCAPE_TO_ASM
)
358 fprintf (file
, ", goes through ASM");
359 if (escape_mask
& ESCAPE_TO_CALL
)
360 fprintf (file
, ", passed to call");
361 if (escape_mask
& ESCAPE_BAD_CAST
)
362 fprintf (file
, ", bad cast");
363 if (escape_mask
& ESCAPE_TO_RETURN
)
364 fprintf (file
, ", returned from func");
365 if (escape_mask
& ESCAPE_TO_PURE_CONST
)
366 fprintf (file
, ", passed to pure/const");
367 if (escape_mask
& ESCAPE_IS_GLOBAL
)
368 fprintf (file
, ", is global var");
369 if (escape_mask
& ESCAPE_IS_PARM
)
370 fprintf (file
, ", is incoming pointer");
371 if (escape_mask
& ESCAPE_UNKNOWN
)
372 fprintf (file
, ", unknown escape");
373 fprintf (file
, " )");
377 if (default_def (var
))
379 fprintf (file
, ", default def: ");
380 print_generic_expr (file
, default_def (var
), dump_flags
);
383 if (may_aliases (var
))
385 fprintf (file
, ", may aliases: ");
386 dump_may_aliases_for (file
, var
);
389 if (get_subvars_for_var (var
))
391 fprintf (file
, ", sub-vars: ");
392 dump_subvars_for (file
, var
);
395 fprintf (file
, "\n");
399 /* Dump variable VAR and its may-aliases to stderr. */
402 debug_variable (tree var
)
404 dump_variable (stderr
, var
);
408 /* Dump various DFA statistics to FILE. */
411 dump_dfa_stats (FILE *file
)
413 struct dfa_stats_d dfa_stats
;
415 unsigned long size
, total
= 0;
416 const char * const fmt_str
= "%-30s%-13s%12s\n";
417 const char * const fmt_str_1
= "%-30s%13lu%11lu%c\n";
418 const char * const fmt_str_3
= "%-43s%11lu%c\n";
420 = lang_hooks
.decl_printable_name (current_function_decl
, 2);
422 collect_dfa_stats (&dfa_stats
);
424 fprintf (file
, "\nDFA Statistics for %s\n\n", funcname
);
426 fprintf (file
, "---------------------------------------------------------\n");
427 fprintf (file
, fmt_str
, "", " Number of ", "Memory");
428 fprintf (file
, fmt_str
, "", " instances ", "used ");
429 fprintf (file
, "---------------------------------------------------------\n");
431 size
= num_referenced_vars
* sizeof (tree
);
433 fprintf (file
, fmt_str_1
, "Referenced variables", (unsigned long)num_referenced_vars
,
434 SCALE (size
), LABEL (size
));
436 size
= dfa_stats
.num_stmt_anns
* sizeof (struct stmt_ann_d
);
438 fprintf (file
, fmt_str_1
, "Statements annotated", dfa_stats
.num_stmt_anns
,
439 SCALE (size
), LABEL (size
));
441 size
= dfa_stats
.num_var_anns
* sizeof (struct var_ann_d
);
443 fprintf (file
, fmt_str_1
, "Variables annotated", dfa_stats
.num_var_anns
,
444 SCALE (size
), LABEL (size
));
446 size
= dfa_stats
.num_uses
* sizeof (tree
*);
448 fprintf (file
, fmt_str_1
, "USE operands", dfa_stats
.num_uses
,
449 SCALE (size
), LABEL (size
));
451 size
= dfa_stats
.num_defs
* sizeof (tree
*);
453 fprintf (file
, fmt_str_1
, "DEF operands", dfa_stats
.num_defs
,
454 SCALE (size
), LABEL (size
));
456 size
= dfa_stats
.num_vuses
* sizeof (tree
*);
458 fprintf (file
, fmt_str_1
, "VUSE operands", dfa_stats
.num_vuses
,
459 SCALE (size
), LABEL (size
));
461 size
= dfa_stats
.num_v_may_defs
* sizeof (tree
*);
463 fprintf (file
, fmt_str_1
, "V_MAY_DEF operands", dfa_stats
.num_v_may_defs
,
464 SCALE (size
), LABEL (size
));
466 size
= dfa_stats
.num_v_must_defs
* sizeof (tree
*);
468 fprintf (file
, fmt_str_1
, "V_MUST_DEF operands", dfa_stats
.num_v_must_defs
,
469 SCALE (size
), LABEL (size
));
471 size
= dfa_stats
.num_phis
* sizeof (struct tree_phi_node
);
473 fprintf (file
, fmt_str_1
, "PHI nodes", dfa_stats
.num_phis
,
474 SCALE (size
), LABEL (size
));
476 size
= dfa_stats
.num_phi_args
* sizeof (struct phi_arg_d
);
478 fprintf (file
, fmt_str_1
, "PHI arguments", dfa_stats
.num_phi_args
,
479 SCALE (size
), LABEL (size
));
481 fprintf (file
, "---------------------------------------------------------\n");
482 fprintf (file
, fmt_str_3
, "Total memory used by DFA/SSA data", SCALE (total
),
484 fprintf (file
, "---------------------------------------------------------\n");
485 fprintf (file
, "\n");
487 if (dfa_stats
.num_phis
)
488 fprintf (file
, "Average number of arguments per PHI node: %.1f (max: %d)\n",
489 (float) dfa_stats
.num_phi_args
/ (float) dfa_stats
.num_phis
,
490 dfa_stats
.max_num_phi_args
);
492 fprintf (file
, "\n");
496 /* Dump DFA statistics on stderr. */
499 debug_dfa_stats (void)
501 dump_dfa_stats (stderr
);
505 /* Collect DFA statistics and store them in the structure pointed to by
509 collect_dfa_stats (struct dfa_stats_d
*dfa_stats_p
)
511 struct pointer_set_t
*pset
;
513 block_stmt_iterator i
;
515 gcc_assert (dfa_stats_p
);
517 memset ((void *)dfa_stats_p
, 0, sizeof (struct dfa_stats_d
));
519 /* Walk all the trees in the function counting references. Start at
520 basic block NUM_FIXED_BLOCKS, but don't stop at block boundaries. */
521 pset
= pointer_set_create ();
523 for (i
= bsi_start (BASIC_BLOCK (NUM_FIXED_BLOCKS
));
524 !bsi_end_p (i
); bsi_next (&i
))
525 walk_tree (bsi_stmt_ptr (i
), collect_dfa_stats_r
, (void *) dfa_stats_p
,
528 pointer_set_destroy (pset
);
533 for (phi
= phi_nodes (bb
); phi
; phi
= PHI_CHAIN (phi
))
535 dfa_stats_p
->num_phis
++;
536 dfa_stats_p
->num_phi_args
+= PHI_NUM_ARGS (phi
);
537 if (PHI_NUM_ARGS (phi
) > dfa_stats_p
->max_num_phi_args
)
538 dfa_stats_p
->max_num_phi_args
= PHI_NUM_ARGS (phi
);
544 /* Callback for walk_tree to collect DFA statistics for a tree and its
548 collect_dfa_stats_r (tree
*tp
, int *walk_subtrees ATTRIBUTE_UNUSED
,
552 struct dfa_stats_d
*dfa_stats_p
= (struct dfa_stats_d
*)data
;
556 switch (ann_type (t
->common
.ann
))
560 dfa_stats_p
->num_stmt_anns
++;
561 dfa_stats_p
->num_defs
+= NUM_SSA_OPERANDS (t
, SSA_OP_DEF
);
562 dfa_stats_p
->num_uses
+= NUM_SSA_OPERANDS (t
, SSA_OP_USE
);
563 dfa_stats_p
->num_v_may_defs
+= NUM_SSA_OPERANDS (t
, SSA_OP_VMAYDEF
);
564 dfa_stats_p
->num_vuses
+= NUM_SSA_OPERANDS (t
, SSA_OP_VUSE
);
565 dfa_stats_p
->num_v_must_defs
+=
566 NUM_SSA_OPERANDS (t
, SSA_OP_VMUSTDEF
);
571 dfa_stats_p
->num_var_anns
++;
583 /*---------------------------------------------------------------------------
584 Miscellaneous helpers
585 ---------------------------------------------------------------------------*/
586 /* Callback for walk_tree. Used to collect variables referenced in
590 find_vars_r (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
592 /* If T is a regular variable that the optimizers are interested
593 in, add it to the list of variables. */
595 add_referenced_var (*tp
);
597 /* Type, _DECL and constant nodes have no interesting children.
599 else if (IS_TYPE_OR_DECL_P (*tp
) || CONSTANT_CLASS_P (*tp
))
605 /* Lookup UID in the referenced_vars hashtable and return the associated
609 referenced_var_lookup (unsigned int uid
)
611 struct int_tree_map
*h
, in
;
613 h
= (struct int_tree_map
*) htab_find_with_hash (referenced_vars
, &in
, uid
);
614 gcc_assert (h
|| uid
== 0);
620 /* Check if TO is in the referenced_vars hash table and insert it if not.
621 Return true if it required insertion. */
624 referenced_var_check_and_insert (tree to
)
626 struct int_tree_map
*h
, in
;
628 unsigned int uid
= DECL_UID (to
);
632 h
= (struct int_tree_map
*) htab_find_with_hash (referenced_vars
, &in
, uid
);
636 /* DECL_UID has already been entered in the table. Verify that it is
637 the same entry as TO. See PR 27793. */
638 gcc_assert (h
->to
== to
);
642 h
= GGC_NEW (struct int_tree_map
);
645 loc
= htab_find_slot_with_hash (referenced_vars
, h
, uid
, INSERT
);
646 *(struct int_tree_map
**) loc
= h
;
650 /* Lookup VAR UID in the default_defs hashtable and return the associated
654 default_def (tree var
)
656 struct int_tree_map
*h
, in
;
657 gcc_assert (SSA_VAR_P (var
));
658 in
.uid
= DECL_UID (var
);
659 h
= (struct int_tree_map
*) htab_find_with_hash (default_defs
, &in
,
666 /* Insert the pair VAR's UID, DEF into the default_defs hashtable. */
669 set_default_def (tree var
, tree def
)
671 struct int_tree_map in
;
672 struct int_tree_map
*h
;
675 gcc_assert (SSA_VAR_P (var
));
676 in
.uid
= DECL_UID (var
);
677 if (!def
&& default_def (var
))
679 loc
= htab_find_slot_with_hash (default_defs
, &in
, DECL_UID (var
), INSERT
);
680 htab_remove_elt (default_defs
, *loc
);
683 gcc_assert (TREE_CODE (def
) == SSA_NAME
);
684 loc
= htab_find_slot_with_hash (default_defs
, &in
, DECL_UID (var
), INSERT
);
685 /* Default definition might be changed by tail call optimization. */
688 h
= GGC_NEW (struct int_tree_map
);
689 h
->uid
= DECL_UID (var
);
691 *(struct int_tree_map
**) loc
= h
;
695 h
= (struct int_tree_map
*) *loc
;
700 /* Add VAR to the list of referenced variables if it isn't already there. */
703 add_referenced_var (tree var
)
707 v_ann
= get_var_ann (var
);
708 gcc_assert (DECL_P (var
));
710 /* Insert VAR into the referenced_vars has table if it isn't present. */
711 if (referenced_var_check_and_insert (var
))
713 /* This is the first time we found this variable, annotate it with
714 attributes that are intrinsic to the variable. */
716 /* Tag's don't have DECL_INITIAL. */
720 /* Scan DECL_INITIAL for pointer variables as they may contain
721 address arithmetic referencing the address of other
723 if (DECL_INITIAL (var
)
724 /* Initializers of external variables are not useful to the
726 && !DECL_EXTERNAL (var
)
727 /* It's not necessary to walk the initial value of non-constant
728 variables because it cannot be propagated by the
730 && (TREE_CONSTANT (var
) || TREE_READONLY (var
)))
731 walk_tree (&DECL_INITIAL (var
), find_vars_r
, NULL
, 0);
736 /* Return the virtual variable associated to the non-scalar variable VAR. */
739 get_virtual_var (tree var
)
743 if (TREE_CODE (var
) == SSA_NAME
)
744 var
= SSA_NAME_VAR (var
);
746 while (TREE_CODE (var
) == REALPART_EXPR
|| TREE_CODE (var
) == IMAGPART_EXPR
747 || handled_component_p (var
))
748 var
= TREE_OPERAND (var
, 0);
750 /* Treating GIMPLE registers as virtual variables makes no sense.
751 Also complain if we couldn't extract a _DECL out of the original
753 gcc_assert (SSA_VAR_P (var
));
754 gcc_assert (!is_gimple_reg (var
));
759 /* Mark all the non-SSA variables found in STMT's operands to be
760 processed by update_ssa. */
763 mark_new_vars_to_rename (tree stmt
)
767 bitmap vars_in_vops_to_rename
;
768 bool found_exposed_symbol
= false;
769 int v_may_defs_before
, v_may_defs_after
;
770 int v_must_defs_before
, v_must_defs_after
;
772 if (TREE_CODE (stmt
) == PHI_NODE
)
776 vars_in_vops_to_rename
= BITMAP_ALLOC (NULL
);
778 /* Before re-scanning the statement for operands, mark the existing
779 virtual operands to be renamed again. We do this because when new
780 symbols are exposed, the virtual operands that were here before due to
781 aliasing will probably be removed by the call to get_stmt_operand.
782 Therefore, we need to flag them to be renamed beforehand.
784 We flag them in a separate bitmap because we don't really want to
785 rename them if there are not any newly exposed symbols in the
786 statement operands. */
787 v_may_defs_before
= NUM_SSA_OPERANDS (stmt
, SSA_OP_VMAYDEF
);
788 v_must_defs_before
= NUM_SSA_OPERANDS (stmt
, SSA_OP_VMUSTDEF
);
790 FOR_EACH_SSA_TREE_OPERAND (val
, stmt
, iter
,
791 SSA_OP_VMAYDEF
| SSA_OP_VUSE
| SSA_OP_VMUSTDEF
)
794 val
= SSA_NAME_VAR (val
);
795 bitmap_set_bit (vars_in_vops_to_rename
, DECL_UID (val
));
798 /* Now force an operand re-scan on the statement and mark any newly
799 exposed variables. */
802 v_may_defs_after
= NUM_SSA_OPERANDS (stmt
, SSA_OP_VMAYDEF
);
803 v_must_defs_after
= NUM_SSA_OPERANDS (stmt
, SSA_OP_VMUSTDEF
);
805 FOR_EACH_SSA_TREE_OPERAND (val
, stmt
, iter
, SSA_OP_ALL_OPERANDS
)
808 found_exposed_symbol
= true;
809 mark_sym_for_renaming (val
);
812 /* If we found any newly exposed symbols, or if there are fewer VDEF
813 operands in the statement, add the variables we had set in
814 VARS_IN_VOPS_TO_RENAME to VARS_TO_RENAME. We need to check for
815 vanishing VDEFs because in those cases, the names that were formerly
816 generated by this statement are not going to be available anymore. */
817 if (found_exposed_symbol
818 || v_may_defs_before
> v_may_defs_after
819 || v_must_defs_before
> v_must_defs_after
)
820 mark_set_for_renaming (vars_in_vops_to_rename
);
822 BITMAP_FREE (vars_in_vops_to_rename
);
825 /* Find all variables within the gimplified statement that were not previously
826 visible to the function and add them to the referenced variables list. */
829 find_new_referenced_vars_1 (tree
*tp
, int *walk_subtrees
,
830 void *data ATTRIBUTE_UNUSED
)
834 if (TREE_CODE (t
) == VAR_DECL
&& !var_ann (t
))
836 add_referenced_var (t
);
837 mark_sym_for_renaming (t
);
840 if (IS_TYPE_OR_DECL_P (t
))
847 find_new_referenced_vars (tree
*stmt_p
)
849 walk_tree (stmt_p
, find_new_referenced_vars_1
, NULL
, NULL
);
853 /* If REF is a handled component reference for a structure, return the
854 base variable. The access range is delimited by bit positions *POFFSET and
855 *POFFSET + *PMAX_SIZE. The access size is *PSIZE bits. If either
856 *PSIZE or *PMAX_SIZE is -1, they could not be determined. If *PSIZE
857 and *PMAX_SIZE are equal, the access is non-variable. */
860 get_ref_base_and_extent (tree exp
, HOST_WIDE_INT
*poffset
,
861 HOST_WIDE_INT
*psize
,
862 HOST_WIDE_INT
*pmax_size
)
864 HOST_WIDE_INT bitsize
= -1;
865 HOST_WIDE_INT maxsize
= -1;
866 tree size_tree
= NULL_TREE
;
867 tree bit_offset
= bitsize_zero_node
;
868 bool seen_variable_array_ref
= false;
870 gcc_assert (!SSA_VAR_P (exp
));
872 /* First get the final access size from just the outermost expression. */
873 if (TREE_CODE (exp
) == COMPONENT_REF
)
874 size_tree
= DECL_SIZE (TREE_OPERAND (exp
, 1));
875 else if (TREE_CODE (exp
) == BIT_FIELD_REF
)
876 size_tree
= TREE_OPERAND (exp
, 1);
879 enum machine_mode mode
= TYPE_MODE (TREE_TYPE (exp
));
881 size_tree
= TYPE_SIZE (TREE_TYPE (exp
));
883 bitsize
= GET_MODE_BITSIZE (mode
);
885 if (size_tree
!= NULL_TREE
)
887 if (! host_integerp (size_tree
, 1))
890 bitsize
= TREE_INT_CST_LOW (size_tree
);
893 /* Initially, maxsize is the same as the accessed element size.
894 In the following it will only grow (or become -1). */
897 /* Compute cumulative bit-offset for nested component-refs and array-refs,
898 and find the ultimate containing object. */
901 switch (TREE_CODE (exp
))
904 bit_offset
= size_binop (PLUS_EXPR
, bit_offset
,
905 TREE_OPERAND (exp
, 2));
910 tree field
= TREE_OPERAND (exp
, 1);
911 tree this_offset
= component_ref_field_offset (exp
);
913 if (this_offset
&& TREE_CODE (this_offset
) == INTEGER_CST
)
915 this_offset
= size_binop (MULT_EXPR
,
916 fold_convert (bitsizetype
,
919 bit_offset
= size_binop (PLUS_EXPR
,
920 bit_offset
, this_offset
);
921 bit_offset
= size_binop (PLUS_EXPR
, bit_offset
,
922 DECL_FIELD_BIT_OFFSET (field
));
926 tree csize
= TYPE_SIZE (TREE_TYPE (TREE_OPERAND (exp
, 0)));
927 /* We need to adjust maxsize to the whole structure bitsize.
928 But we can subtract any constant offset seen sofar,
929 because that would get us out of the structure otherwise. */
931 && csize
&& host_integerp (csize
, 1))
933 maxsize
= (TREE_INT_CST_LOW (csize
)
934 - TREE_INT_CST_LOW (bit_offset
));
943 case ARRAY_RANGE_REF
:
945 tree index
= TREE_OPERAND (exp
, 1);
946 tree low_bound
= array_ref_low_bound (exp
);
947 tree unit_size
= array_ref_element_size (exp
);
949 if (! integer_zerop (low_bound
))
950 index
= fold_build2 (MINUS_EXPR
, TREE_TYPE (index
),
952 index
= size_binop (MULT_EXPR
,
953 fold_convert (sizetype
, index
), unit_size
);
954 if (TREE_CODE (index
) == INTEGER_CST
)
956 index
= size_binop (MULT_EXPR
,
957 fold_convert (bitsizetype
, index
),
959 bit_offset
= size_binop (PLUS_EXPR
, bit_offset
, index
);
961 /* An array ref with a constant index up in the structure
962 hierarchy will constrain the size of any variable array ref
963 lower in the access hierarchy. */
964 seen_variable_array_ref
= false;
968 tree asize
= TYPE_SIZE (TREE_TYPE (TREE_OPERAND (exp
, 0)));
969 /* We need to adjust maxsize to the whole array bitsize.
970 But we can subtract any constant offset seen sofar,
971 because that would get us outside of the array otherwise. */
973 && asize
&& host_integerp (asize
, 1))
975 maxsize
= (TREE_INT_CST_LOW (asize
)
976 - TREE_INT_CST_LOW (bit_offset
));
981 /* Remember that we have seen an array ref with a variable
983 seen_variable_array_ref
= true;
992 bit_offset
= size_binop (PLUS_EXPR
, bit_offset
,
993 bitsize_int (bitsize
));
996 case VIEW_CONVERT_EXPR
:
997 /* ??? We probably should give up here and bail out. */
1004 exp
= TREE_OPERAND (exp
, 0);
1008 /* We need to deal with variable arrays ending structures such as
1009 struct { int length; int a[1]; } x; x.a[d]
1010 struct { struct { int a; int b; } a[1]; } x; x.a[d].a
1011 struct { struct { int a[1]; } a[1]; } x; x.a[0][d], x.a[d][0]
1012 where we do not know maxsize for variable index accesses to
1013 the array. The simplest way to conservatively deal with this
1014 is to punt in the case that offset + maxsize reaches the
1015 base type boundary. */
1016 if (seen_variable_array_ref
1018 && host_integerp (TYPE_SIZE (TREE_TYPE (exp
)), 1)
1019 && TREE_INT_CST_LOW (bit_offset
) + maxsize
1020 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp
))))
1023 /* ??? Due to negative offsets in ARRAY_REF we can end up with
1024 negative bit_offset here. We might want to store a zero offset
1026 *poffset
= TREE_INT_CST_LOW (bit_offset
);
1028 *pmax_size
= maxsize
;