2005-08-12 Richard Guenther PR tree-optimization/22548 PR tree-optimization/22555 * Makefile.in (tree-ssa-structalias.o): Depend on $(PARAMS_H). * expr.c (get_inner_reference): Fold constant offsets in COMPONENT_REF and ARRAY_REF into bit_offset, if possible. Handles a.a[1].a[i]. * params.def (salias-max-array-elements): New parameter. * params.h (SALIAS_MAX_ARRAY_ELEMENTS): Define. * doc/invoke.texi (salias-max-array-elements): Document. * tree-dfa.c (okay_component_ref_for_subvars): Do not give up, if one structure field is an array. Use more precise results from get_inner_reference. * tree-flow-inline.h (var_can_have_subvars): We also handle arrays now. * tree-flow.h (struct fieldoff): Use separate type and offset field instead of storing FIELD_DECL in field. * tree-ssa-alias.c (create_sft): We now take field type as 2nd argument. (find_used_portions): Handle ARRAY_REF as COMPONENT_REF. Use more precise information from get_inner_reference. (create_overlap_variables_for): Do not give up, if one structure field is an array. Adjust for field now storing field type. * tree-ssa-structalias.c (create_variable_info_for): Likewise. (fieldoff_compare): Likewise. (push_fields_onto_fieldstack): Likewise. Handle ARRAY_TYPE. (params.h): Include. (offset_overlaps_with_access): Avoid possible integer overflow. (get_constraint_for_component_ref): Disable assert for accessing non-existant fields. (find_func_aliases): As for aggregate types, add anyoffset constraint to array references. * tree-ssa-loop-ivopts.c (get_ref_tag): Handle subvars. (rewrite_use): Mark stmt for renaming. * tree-ssa-operands.c (parse_ssa_operands): Handle ARRAY_REF for creating MUST_DEFs. (get_expr_operands): Treat ARRAY_REF like COMPONENT_REF wrt subvars. * tree-ssa-loop.c (pass_iv_optimize): Schedule TODO_update_ssa. Index: Makefile.in =================================================================== RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v retrieving revision 1.1535 diff -c -3 -p -r1.1535 Makefile.in *** Makefile.in 6 Aug 2005 13:25:52 -0000 1.1535 --- Makefile.in 12 Aug 2005 11:10:54 -0000 *************** stor-layout.o : stor-layout.c $(CONFIG_H *** 1728,1734 **** toplev.h tree-ssa-structalias.o: tree-ssa-structalias.c tree-ssa-structalias.h \ $(SYSTEM_H) $(CONFIG_H) $(GGC_H) $(TREE_H) $(TREE_FLOW_H) \ ! $(TM_H) coretypes.h cgraph.h tree-pass.h $(TIMEVAR_H) tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \ toplev.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h \ --- 1728,1734 ---- toplev.h tree-ssa-structalias.o: tree-ssa-structalias.c tree-ssa-structalias.h \ $(SYSTEM_H) $(CONFIG_H) $(GGC_H) $(TREE_H) $(TREE_FLOW_H) \ ! $(TM_H) coretypes.h cgraph.h tree-pass.h $(TIMEVAR_H) $(PARAMS_H) tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \ toplev.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h \ Index: expr.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/expr.c,v retrieving revision 1.808 diff -c -3 -p -r1.808 expr.c *** expr.c 8 Aug 2005 19:47:59 -0000 1.808 --- expr.c 12 Aug 2005 11:10:54 -0000 *************** get_inner_reference (tree exp, HOST_WIDE *** 5455,5460 **** --- 5455,5461 ---- tree size_tree = 0; enum machine_mode mode = VOIDmode; tree offset = size_zero_node; + tree coffset = size_zero_node; tree bit_offset = bitsize_zero_node; tree tem; *************** get_inner_reference (tree exp, HOST_WIDE *** 5514,5520 **** if (this_offset == 0) break; ! offset = size_binop (PLUS_EXPR, offset, this_offset); bit_offset = size_binop (PLUS_EXPR, bit_offset, DECL_FIELD_BIT_OFFSET (field)); --- 5515,5525 ---- if (this_offset == 0) break; ! if (TREE_CODE (this_offset) == INTEGER_CST) ! coffset = size_binop (PLUS_EXPR, coffset, this_offset); ! else ! offset = size_binop (PLUS_EXPR, offset, this_offset); ! bit_offset = size_binop (PLUS_EXPR, bit_offset, DECL_FIELD_BIT_OFFSET (field)); *************** get_inner_reference (tree exp, HOST_WIDE *** 5536,5546 **** if (! integer_zerop (low_bound)) index = fold_build2 (MINUS_EXPR, TREE_TYPE (index), index, low_bound); ! ! offset = size_binop (PLUS_EXPR, offset, ! size_binop (MULT_EXPR, ! convert (sizetype, index), ! unit_size)); } break; --- 5541,5551 ---- if (! integer_zerop (low_bound)) index = fold_build2 (MINUS_EXPR, TREE_TYPE (index), index, low_bound); ! index = size_binop (MULT_EXPR, convert (sizetype, index), unit_size); ! if (TREE_CODE (index) == INTEGER_CST) ! coffset = size_binop (PLUS_EXPR, coffset, index); ! else ! offset = size_binop (PLUS_EXPR, offset, index); } break; *************** get_inner_reference (tree exp, HOST_WIDE *** 5575,5590 **** } done: ! /* If OFFSET is constant, see if we can return the whole thing as a ! constant bit position. Otherwise, split it up. */ ! if (host_integerp (offset, 0) ! && 0 != (tem = size_binop (MULT_EXPR, convert (bitsizetype, offset), bitsize_unit_node)) && 0 != (tem = size_binop (PLUS_EXPR, tem, bit_offset)) && host_integerp (tem, 0)) ! *pbitpos = tree_low_cst (tem, 0), *poffset = 0; else ! *pbitpos = tree_low_cst (bit_offset, 0), *poffset = offset; *pmode = mode; return exp; --- 5580,5603 ---- } done: ! /* See, if we can return COFFSET in the constant bit position, otherwise ! fold into OFFSET. */ ! if (host_integerp (coffset, 0) ! && 0 != (tem = size_binop (MULT_EXPR, convert (bitsizetype, coffset), bitsize_unit_node)) && 0 != (tem = size_binop (PLUS_EXPR, tem, bit_offset)) && host_integerp (tem, 0)) ! { ! *pbitpos = tree_low_cst (tem, 0); ! *poffset = offset; ! } else ! { ! *pbitpos = tree_low_cst (bit_offset, 0); ! *poffset = size_binop (PLUS_EXPR, coffset, offset); ! } ! if (integer_zerop (*poffset)) ! *poffset = NULL_TREE; *pmode = mode; return exp; Index: params.def =================================================================== RCS file: /cvs/gcc/gcc/gcc/params.def,v retrieving revision 1.66 diff -c -3 -p -r1.66 params.def *** params.def 5 Aug 2005 02:42:04 -0000 1.66 --- params.def 12 Aug 2005 11:10:54 -0000 *************** DEFPARAM (PARAM_SALIAS_MAX_IMPLICIT_FIEL *** 47,53 **** "salias-max-implicit-fields", "The maximum number of fields in a structure variable without direct structure accesses that GCC will attempt to track separately", 5, 0, 0) ! /* The maximum structure size at which the scalar replacement of aggregates (SRA) pass will perform block copies. The default value, 0, implies that GCC will select the most appropriate size --- 47,60 ---- "salias-max-implicit-fields", "The maximum number of fields in a structure variable without direct structure accesses that GCC will attempt to track separately", 5, 0, 0) ! ! /* The maximum number of array elements structure aliasing will decompose ! an array for. The default is 4. */ ! DEFPARAM (PARAM_SALIAS_MAX_ARRAY_ELEMENTS, ! "salias-max-array-elements", ! "The maximum number of elements in an array for wich we track its elements separately", ! 4, 0, 0) ! /* The maximum structure size at which the scalar replacement of aggregates (SRA) pass will perform block copies. The default value, 0, implies that GCC will select the most appropriate size Index: params.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/params.h,v retrieving revision 1.32 diff -c -3 -p -r1.32 params.h *** params.h 5 Aug 2005 02:42:05 -0000 1.32 --- params.h 12 Aug 2005 11:10:54 -0000 *************** typedef enum compiler_param *** 91,96 **** --- 91,98 ---- /* Macros for the various parameters. */ #define SALIAS_MAX_IMPLICIT_FIELDS \ PARAM_VALUE (PARAM_SALIAS_MAX_IMPLICIT_FIELDS) + #define SALIAS_MAX_ARRAY_ELEMENTS \ + PARAM_VALUE (PARAM_SALIAS_MAX_ARRAY_ELEMENTS) #define SRA_MAX_STRUCTURE_SIZE \ PARAM_VALUE (PARAM_SRA_MAX_STRUCTURE_SIZE) #define SRA_MAX_STRUCTURE_COUNT \ Index: tree-dfa.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-dfa.c,v retrieving revision 2.63 diff -c -3 -p -r2.63 tree-dfa.c *** tree-dfa.c 28 Jul 2005 16:29:52 -0000 2.63 --- tree-dfa.c 12 Aug 2005 11:10:54 -0000 *************** okay_component_ref_for_subvars (tree ref *** 810,817 **** *poffset = 0; *psize = (unsigned int) -1; - if (ref_contains_array_ref (ref)) - return result; ref = get_inner_reference (ref, &bitsize, &bitpos, &offset, &mode, &unsignedp, &volatilep, false); if (TREE_CODE (ref) == INDIRECT_REF) --- 810,815 ---- *************** okay_component_ref_for_subvars (tree ref *** 823,828 **** --- 821,834 ---- if (get_subvars_for_var (ref) != NULL) return ref; } + else if (offset && bitsize != -1 && SSA_VAR_P (ref)) + { + /* We assume the offset part is positive only. A resonable assumption. */ + *poffset = bitpos; + *psize = (unsigned int) -1; + if (get_subvars_for_var (ref) != NULL) + return ref; + } else if (SSA_VAR_P (ref)) { if (get_subvars_for_var (ref) != NULL) Index: tree-flow-inline.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-flow-inline.h,v retrieving revision 2.55 diff -c -3 -p -r2.55 tree-flow-inline.h *** tree-flow-inline.h 28 Jul 2005 16:29:52 -0000 2.55 --- tree-flow-inline.h 12 Aug 2005 11:10:54 -0000 *************** get_subvar_at (tree var, unsigned HOST_W *** 1477,1484 **** static inline bool var_can_have_subvars (tree v) { ! return (AGGREGATE_TYPE_P (TREE_TYPE (v)) && ! TREE_CODE (TREE_TYPE (v)) != ARRAY_TYPE); } --- 1477,1483 ---- static inline bool var_can_have_subvars (tree v) { ! return (AGGREGATE_TYPE_P (TREE_TYPE (v))); } Index: tree-flow.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-flow.h,v retrieving revision 2.131 diff -c -3 -p -r2.131 tree-flow.h *** tree-flow.h 27 Jul 2005 13:26:53 -0000 2.131 --- tree-flow.h 12 Aug 2005 11:10:54 -0000 *************** tree maybe_fold_tmr (tree); *** 876,882 **** struct fieldoff { ! tree field; HOST_WIDE_INT offset; }; typedef struct fieldoff fieldoff_s; --- 876,883 ---- struct fieldoff { ! tree type; ! tree size; HOST_WIDE_INT offset; }; typedef struct fieldoff fieldoff_s; Index: tree-ssa-alias.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-ssa-alias.c,v retrieving revision 2.109 diff -c -3 -p -r2.109 tree-ssa-alias.c *** tree-ssa-alias.c 28 Jul 2005 16:29:53 -0000 2.109 --- tree-ssa-alias.c 12 Aug 2005 11:10:54 -0000 *************** static tree *** 2502,2508 **** create_sft (tree var, tree field) { var_ann_t ann; ! tree subvar = create_tmp_var_raw (TREE_TYPE (field), "SFT"); /* We need to copy the various flags from VAR to SUBVAR, so that they are is_global_var iff the original variable was. */ --- 2504,2510 ---- create_sft (tree var, tree field) { var_ann_t ann; ! tree subvar = create_tmp_var_raw (field, "SFT"); /* We need to copy the various flags from VAR to SUBVAR, so that they are is_global_var iff the original variable was. */ *************** create_overlap_variables_for (tree var) *** 2559,2567 **** for (i = 0; VEC_iterate (fieldoff_s, fieldstack, i, fo); i++) { ! if (!DECL_SIZE (fo->field) ! || TREE_CODE (DECL_SIZE (fo->field)) != INTEGER_CST ! || TREE_CODE (TREE_TYPE (fo->field)) == ARRAY_TYPE || fo->offset < 0) { notokay = true; --- 2561,2568 ---- for (i = 0; VEC_iterate (fieldoff_s, fieldstack, i, fo); i++) { ! if (! fo->size ! || TREE_CODE (fo->size) != INTEGER_CST || fo->offset < 0) { notokay = true; *************** create_overlap_variables_for (tree var) *** 2613,2620 **** HOST_WIDE_INT fosize; tree currfotype; ! fosize = TREE_INT_CST_LOW (DECL_SIZE (fo->field)); ! currfotype = TREE_TYPE (fo->field); /* If this field isn't in the used portion, or it has the exact same offset and size as the last --- 2622,2629 ---- HOST_WIDE_INT fosize; tree currfotype; ! fosize = TREE_INT_CST_LOW (fo->size); ! currfotype = fo->type; /* If this field isn't in the used portion, or it has the exact same offset and size as the last *************** create_overlap_variables_for (tree var) *** 2631,2637 **** sv->offset = fo->offset; sv->size = fosize; sv->next = *subvars; ! sv->var = create_sft (var, fo->field); if (dump_file) { --- 2640,2646 ---- sv->offset = fo->offset; sv->size = fosize; sv->next = *subvars; ! sv->var = create_sft (var, fo->type); if (dump_file) { *************** find_used_portions (tree *tp, int *walk_ *** 2677,2682 **** --- 2686,2692 ---- switch (TREE_CODE (*tp)) { case COMPONENT_REF: + case ARRAY_REF: { HOST_WIDE_INT bitsize; HOST_WIDE_INT bitpos; *************** find_used_portions (tree *tp, int *walk_ *** 2705,2710 **** --- 2715,2742 ---- *walk_subtrees = 0; return NULL_TREE; } + else if (DECL_P (ref) && offset && bitsize != -1) + { + if (DECL_SIZE (ref) + && var_can_have_subvars (ref) + && TREE_CODE (DECL_SIZE (ref)) == INTEGER_CST) + { + used_part_t up; + size_t uid = DECL_UID (ref); + + up = get_or_create_used_part_for (uid); + + if (bitpos <= up->minused) + up->minused = bitpos; + up->maxused = TREE_INT_CST_LOW (DECL_SIZE (ref)); + + up->implicit_uses = true; + up_insert (uid, up); + + *walk_subtrees = 0; + return NULL_TREE; + } + } else if (DECL_P (ref)) { if (DECL_SIZE (ref) Index: tree-ssa-loop-ivopts.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-ssa-loop-ivopts.c,v retrieving revision 2.86 diff -c -3 -p -r2.86 tree-ssa-loop-ivopts.c *** tree-ssa-loop-ivopts.c 27 Jul 2005 13:26:55 -0000 2.86 --- tree-ssa-loop-ivopts.c 12 Aug 2005 11:10:54 -0000 *************** unshare_and_remove_ssa_names (tree ref) *** 5437,5447 **** and extracts this single useful piece of information. */ static tree ! get_ref_tag (tree ref) { ! tree var = get_base_address (ref); tree tag; if (!var) return NULL_TREE; --- 5437,5462 ---- and extracts this single useful piece of information. */ static tree ! get_ref_tag (tree ref_) { ! tree var = get_base_address (ref_); ! unsigned HOST_WIDE_INT offset, size; ! tree ref = okay_component_ref_for_subvars (ref_, &offset, &size); tree tag; + if (ref) + { + subvar_t svars = get_subvars_for_var (ref); + subvar_t sv; + for (sv = svars; sv; sv = sv->next) + { + bool exact; + if (overlap_subvar (offset, size, sv, &exact) + && exact) + return sv->var; + } + } + if (!var) return NULL_TREE; *************** rewrite_use (struct ivopts_data *data, *** 5755,5760 **** --- 5770,5776 ---- gcc_unreachable (); } update_stmt (use->stmt); + mark_new_vars_to_rename (use->stmt); } /* Rewrite the uses using the selected induction variables. */ Index: tree-ssa-loop.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-ssa-loop.c,v retrieving revision 2.33 diff -c -3 -p -r2.33 tree-ssa-loop.c *** tree-ssa-loop.c 19 Jul 2005 00:44:45 -0000 2.33 --- tree-ssa-loop.c 12 Aug 2005 11:10:54 -0000 *************** struct tree_opt_pass pass_iv_optimize = *** 435,441 **** 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ ! TODO_dump_func | TODO_verify_loops, /* todo_flags_finish */ 0 /* letter */ }; --- 460,467 ---- 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ ! TODO_dump_func | TODO_verify_loops ! | TODO_update_ssa, /* todo_flags_finish */ 0 /* letter */ }; Index: tree-ssa-operands.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-ssa-operands.c,v retrieving revision 2.100 diff -c -3 -p -r2.100 tree-ssa-operands.c *** tree-ssa-operands.c 2 Aug 2005 11:46:44 -0000 2.100 --- tree-ssa-operands.c 12 Aug 2005 11:10:54 -0000 *************** parse_ssa_operands (tree stmt) *** 897,904 **** if (TREE_CODE (lhs) == VIEW_CONVERT_EXPR) lhs = TREE_OPERAND (lhs, 0); ! if (TREE_CODE (lhs) != ARRAY_REF ! && TREE_CODE (lhs) != ARRAY_RANGE_REF && TREE_CODE (lhs) != BIT_FIELD_REF && TREE_CODE (lhs) != REALPART_EXPR && TREE_CODE (lhs) != IMAGPART_EXPR) --- 897,903 ---- if (TREE_CODE (lhs) == VIEW_CONVERT_EXPR) lhs = TREE_OPERAND (lhs, 0); ! if (TREE_CODE (lhs) != ARRAY_RANGE_REF && TREE_CODE (lhs) != BIT_FIELD_REF && TREE_CODE (lhs) != REALPART_EXPR && TREE_CODE (lhs) != IMAGPART_EXPR) *************** get_expr_operands (tree stmt, tree *expr *** 1288,1316 **** case ARRAY_REF: case ARRAY_RANGE_REF: - /* Treat array references as references to the virtual variable - representing the array. The virtual variable for an ARRAY_REF - is the VAR_DECL for the array. */ - - /* Add the virtual variable for the ARRAY_REF to VDEFS or VUSES - according to the value of IS_DEF. Recurse if the LHS of the - ARRAY_REF node is not a regular variable. */ - if (SSA_VAR_P (TREE_OPERAND (expr, 0))) - add_stmt_operand (expr_p, s_ann, flags); - else - get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags); - - get_expr_operands (stmt, &TREE_OPERAND (expr, 1), opf_none); - get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_none); - get_expr_operands (stmt, &TREE_OPERAND (expr, 3), opf_none); - return; - case COMPONENT_REF: case REALPART_EXPR: case IMAGPART_EXPR: { tree ref; unsigned HOST_WIDE_INT offset, size; /* This component ref becomes an access to all of the subvariables it can touch, if we can determine that, but *NOT* the real one. If we can't determine which fields we could touch, the recursion --- 1287,1299 ---- case ARRAY_REF: case ARRAY_RANGE_REF: case COMPONENT_REF: case REALPART_EXPR: case IMAGPART_EXPR: { tree ref; unsigned HOST_WIDE_INT offset, size; + bool none = true; /* This component ref becomes an access to all of the subvariables it can touch, if we can determine that, but *NOT* the real one. If we can't determine which fields we could touch, the recursion *************** get_expr_operands (tree stmt, tree *expr *** 1328,1342 **** if (overlap_subvar (offset, size, sv, &exact)) { int subvar_flags = flags; if (!exact) subvar_flags &= ~opf_kill_def; add_stmt_operand (&sv->var, s_ann, subvar_flags); } } } ! else ! get_expr_operands (stmt, &TREE_OPERAND (expr, 0), ! flags & ~opf_kill_def); if (code == COMPONENT_REF) { --- 1311,1327 ---- if (overlap_subvar (offset, size, sv, &exact)) { int subvar_flags = flags; + none = false; if (!exact) subvar_flags &= ~opf_kill_def; add_stmt_operand (&sv->var, s_ann, subvar_flags); } } + if (! none) + flags |= opf_no_vops; } ! get_expr_operands (stmt, &TREE_OPERAND (expr, 0), ! flags & ~opf_kill_def); if (code == COMPONENT_REF) { *************** get_expr_operands (tree stmt, tree *expr *** 1344,1349 **** --- 1329,1341 ---- s_ann->has_volatile_ops = true; get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_none); } + else if (code == ARRAY_REF + || code == ARRAY_RANGE_REF) + { + get_expr_operands (stmt, &TREE_OPERAND (expr, 1), opf_none); + get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_none); + get_expr_operands (stmt, &TREE_OPERAND (expr, 3), opf_none); + } return; } case WITH_SIZE_EXPR: *************** get_expr_operands (tree stmt, tree *expr *** 1374,1381 **** op = TREE_OPERAND (expr, 0); if (TREE_CODE (op) == WITH_SIZE_EXPR) op = TREE_OPERAND (expr, 0); ! if (TREE_CODE (op) == ARRAY_REF ! || TREE_CODE (op) == ARRAY_RANGE_REF || TREE_CODE (op) == REALPART_EXPR || TREE_CODE (op) == IMAGPART_EXPR) subflags = opf_is_def; --- 1366,1372 ---- op = TREE_OPERAND (expr, 0); if (TREE_CODE (op) == WITH_SIZE_EXPR) op = TREE_OPERAND (expr, 0); ! if (TREE_CODE (op) == ARRAY_RANGE_REF || TREE_CODE (op) == REALPART_EXPR || TREE_CODE (op) == IMAGPART_EXPR) subflags = opf_is_def; Index: tree-ssa-structalias.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-ssa-structalias.c,v retrieving revision 2.26 diff -c -3 -p -r2.26 tree-ssa-structalias.c *** tree-ssa-structalias.c 6 Aug 2005 13:25:58 -0000 2.26 --- tree-ssa-structalias.c 12 Aug 2005 11:10:54 -0000 *************** Foundation, Inc., 51 Franklin Street, Fi *** 48,53 **** --- 48,54 ---- #include "timevar.h" #include "alloc-pool.h" #include "splay-tree.h" + #include "params.h" #include "tree-ssa-structalias.h" /* The idea behind this analyzer is to generate set constraints from the *************** offset_overlaps_with_access (const unsig *** 1989,1997 **** { if (fieldpos == accesspos && fieldsize == accesssize) return true; ! if (accesspos >= fieldpos && accesspos < (fieldpos + fieldsize)) return true; ! if (accesspos < fieldpos && (accesspos + accesssize > fieldpos)) return true; return false; --- 1990,1998 ---- { if (fieldpos == accesspos && fieldsize == accesssize) return true; ! if (accesspos >= fieldpos && (accesspos - fieldpos) < fieldsize) return true; ! if (accesspos < fieldpos && accesssize > (fieldpos - accesspos)) return true; return false; *************** get_constraint_for_component_ref (tree t *** 2075,2082 **** } /* assert that we found *some* field there. The user couldn't be accessing *only* padding. */ ! ! gcc_assert (curr); } else if (dump_file && (dump_flags & TDF_DETAILS)) --- 2076,2084 ---- } /* assert that we found *some* field there. The user couldn't be accessing *only* padding. */ ! /* Still the user could access one past the end of an array ! embedded in a struct resulting in accessing *only* padding. */ ! /* gcc_assert (curr); */ } else if (dump_file && (dump_flags & TDF_DETAILS)) *************** find_func_aliases (tree t, struct alias_ *** 2829,2835 **** of the RHS. */ if (rhs.type == ADDRESSOF && !(get_varinfo (rhs.var)->is_special_var) ! && AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (rhsop)))) { rhs.var = anyoffset_id; rhs.type = ADDRESSOF; --- 2831,2839 ---- of the RHS. */ if (rhs.type == ADDRESSOF && !(get_varinfo (rhs.var)->is_special_var) ! && (AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (rhsop))) ! || TREE_CODE (TREE_TYPE (TREE_OPERAND (rhsop, 0))) == ARRAY_TYPE ! || TREE_CODE (TREE_OPERAND (rhsop, 0)) == ARRAY_REF)) { rhs.var = anyoffset_id; rhs.type = ADDRESSOF; *************** fieldoff_compare (const void *pa, const *** 2939,2946 **** if (foa->offset != fob->offset) return foa->offset - fob->offset; ! foasize = TREE_INT_CST_LOW (DECL_SIZE (foa->field)); ! fobsize = TREE_INT_CST_LOW (DECL_SIZE (fob->field)); return foasize - fobsize; } --- 2943,2950 ---- if (foa->offset != fob->offset) return foa->offset - fob->offset; ! foasize = TREE_INT_CST_LOW (foa->size); ! fobsize = TREE_INT_CST_LOW (fob->size); return foasize - fobsize; } *************** push_fields_onto_fieldstack (tree type, *** 2968,2973 **** --- 2972,3026 ---- tree field; int count = 0; + if (TREE_CODE (type) == ARRAY_TYPE) + { + tree sz = TYPE_SIZE (type); + tree elsz = TYPE_SIZE (TREE_TYPE (type)); + HOST_WIDE_INT nr; + int i; + if (! sz || ! host_integerp (sz, 1) + || ! elsz || ! host_integerp (elsz, 1)) + return 0; + nr = TREE_INT_CST_LOW (sz) / TREE_INT_CST_LOW (elsz); + if (nr > SALIAS_MAX_ARRAY_ELEMENTS) + return 0; + for (i = 0; itype = TREE_TYPE (type); + pair->size = elsz; + pair->offset = offset + i * TREE_INT_CST_LOW (elsz); + count++; + } + else + count += pushed; + } + /*return 1;*/ + } + else + { for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) if (TREE_CODE (field) == FIELD_DECL) { *************** push_fields_onto_fieldstack (tree type, *** 2996,3009 **** fieldoff_s *pair; pair = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL); ! pair->field = field; pair->offset = offset + bitpos_of_field (field); count++; } else count += pushed; } ! return count; } --- 3049,3063 ---- fieldoff_s *pair; pair = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL); ! pair->type = TREE_TYPE (field); ! pair->size = DECL_SIZE (field); pair->offset = offset + bitpos_of_field (field); count++; } else count += pushed; } ! } return count; } *************** create_variable_info_for (tree decl, con *** 3060,3066 **** vi->has_union = hasunion; if (!TYPE_SIZE (decltype) || TREE_CODE (TYPE_SIZE (decltype)) != INTEGER_CST - || TREE_CODE (decltype) == ARRAY_TYPE || TREE_CODE (decltype) == UNION_TYPE || TREE_CODE (decltype) == QUAL_UNION_TYPE) { --- 3114,3119 ---- *************** create_variable_info_for (tree decl, con *** 3088,3100 **** unsigned int newindex = VEC_length (varinfo_t, varmap); fieldoff_s *fo = NULL; unsigned int i; - tree field; for (i = 0; !notokay && VEC_iterate (fieldoff_s, fieldstack, i, fo); i++) { ! if (!DECL_SIZE (fo->field) ! || TREE_CODE (DECL_SIZE (fo->field)) != INTEGER_CST ! || TREE_CODE (TREE_TYPE (fo->field)) == ARRAY_TYPE || fo->offset < 0) { notokay = true; --- 3141,3151 ---- unsigned int newindex = VEC_length (varinfo_t, varmap); fieldoff_s *fo = NULL; unsigned int i; for (i = 0; !notokay && VEC_iterate (fieldoff_s, fieldstack, i, fo); i++) { ! if (! fo->size ! || TREE_CODE (fo->size) != INTEGER_CST || fo->offset < 0) { notokay = true; *************** create_variable_info_for (tree decl, con *** 3121,3128 **** return index; } ! field = fo->field; ! vi->size = TREE_INT_CST_LOW (DECL_SIZE (field)); vi->offset = fo->offset; for (i = 1; VEC_iterate (fieldoff_s, fieldstack, i, fo); i++) { --- 3172,3178 ---- return index; } ! vi->size = TREE_INT_CST_LOW (fo->size); vi->offset = fo->offset; for (i = 1; VEC_iterate (fieldoff_s, fieldstack, i, fo); i++) { *************** create_variable_info_for (tree decl, con *** 3130,3143 **** const char *newname; char *tempname; - field = fo->field; newindex = VEC_length (varinfo_t, varmap); ! asprintf (&tempname, "%s.%s", vi->name, alias_get_name (field)); newname = ggc_strdup (tempname); free (tempname); newvi = new_var_info (decl, newindex, newname, newindex); newvi->offset = fo->offset; ! newvi->size = TREE_INT_CST_LOW (DECL_SIZE (field)); newvi->fullsize = vi->fullsize; insert_into_field_list (vi, newvi); VEC_safe_push (varinfo_t, heap, varmap, newvi); --- 3180,3192 ---- const char *newname; char *tempname; newindex = VEC_length (varinfo_t, varmap); ! asprintf (&tempname, "%s.%u", vi->name, i); newname = ggc_strdup (tempname); free (tempname); newvi = new_var_info (decl, newindex, newname, newindex); newvi->offset = fo->offset; ! newvi->size = TREE_INT_CST_LOW (fo->size); newvi->fullsize = vi->fullsize; insert_into_field_list (vi, newvi); VEC_safe_push (varinfo_t, heap, varmap, newvi); Index: doc/invoke.texi =================================================================== RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v retrieving revision 1.666 diff -c -3 -p -r1.666 invoke.texi *** doc/invoke.texi 7 Aug 2005 02:39:12 -0000 1.666 --- doc/invoke.texi 12 Aug 2005 11:11:03 -0000 *************** The maximum number of fields in a variab *** 5649,5654 **** --- 5649,5658 ---- structure accesses for which structure aliasing will consider trying to track each field. The default is 5 + @item salias-max-array-elements + The maximum number of elements an array can have and its elements + still be tracked individually by structure aliasing. The default is 4 + @item sra-max-structure-size The maximum structure size, in bytes, at which the scalar replacement of aggregates (SRA) optimization will perform block copies. The