diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/tree-flow-inline.h | 21 | ||||
-rw-r--r-- | gcc/tree-ssa-alias.c | 2 | ||||
-rw-r--r-- | gcc/tree-ssa-operands.c | 8 | ||||
-rw-r--r-- | gcc/tree-ssa-structalias.c | 18 |
5 files changed, 58 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 93bd4e1..65aba5c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2006-01-06 Andrew Pinski <pinskia@physics.uc.edu> + + PR tree-opt/25528 + * tree-ssa-alias.c (find_used_portions): Handle REALPART_EXPR + and IMAGPART_EXPR. + * tree-flow-inline.h (var_can_have_subvars): Handle complex types + on non gimple variables. Also add checks at the top for decls and + mtags. + * tree-ssa-structalias.c (push_fields_onto_fieldstack): Handle + complex types. + * tree-ssa-operands.c (parse_ssa_operands): Handle REALPART_EXPR + and IMAGPART_EXPR for creating MUST_DEFs. + (get_expr_operands): Handle SSA_NAME, STRUCT_FIELD_TAG, TYPE_MEMORY_TAG, + and NAME_MEMORY_TAG separately from the DECLs. + 2006-01-06 Richard Guenther <rguenther@suse.de> * tree-dfa.c (mark_new_vars_to_rename): Create stmt diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h index 94e1972..3f8e89d 100644 --- a/gcc/tree-flow-inline.h +++ b/gcc/tree-flow-inline.h @@ -1490,13 +1490,28 @@ get_subvar_at (tree var, unsigned HOST_WIDE_INT offset) /* Return true if V is a tree that we can have subvars for. Normally, this is any aggregate type, however, due to implementation - limitations ATM, we exclude array types as well. */ + limitations ATM, we exclude array types as well. Also complex + types which are not gimple registers can have subvars. */ static inline bool var_can_have_subvars (tree v) { - return (AGGREGATE_TYPE_P (TREE_TYPE (v)) && - TREE_CODE (TREE_TYPE (v)) != ARRAY_TYPE); + /* Non decls or memory tags can never have subvars. */ + if (!DECL_P (v) || MTAG_P (v)) + return false; + + /* Aggregates besides arrays can have subvars. */ + if (AGGREGATE_TYPE_P (TREE_TYPE (v)) + && TREE_CODE (TREE_TYPE (v)) != ARRAY_TYPE) + return true; + + /* Complex types variables which are not also a gimple register can + have subvars. */ + if (TREE_CODE (TREE_TYPE (v)) == COMPLEX_TYPE + && !DECL_COMPLEX_GIMPLE_REG_P (v)) + return true; + + return false; } diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index ee6a6e6..cb5dead 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -2694,6 +2694,8 @@ find_used_portions (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) { switch (TREE_CODE (*tp)) { + case REALPART_EXPR: + case IMAGPART_EXPR: case COMPONENT_REF: { HOST_WIDE_INT bitsize; diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index b7319de..60973ce 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -734,9 +734,7 @@ parse_ssa_operands (tree stmt) 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) + && TREE_CODE (lhs) != BIT_FIELD_REF) lhs_flags |= opf_kill_def; get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), lhs_flags); @@ -1065,6 +1063,10 @@ get_expr_operands (tree stmt, tree *expr_p, int flags) case STRUCT_FIELD_TAG: case TYPE_MEMORY_TAG: case NAME_MEMORY_TAG: + + add_stmt_operand (expr_p, s_ann, flags); + return; + case VAR_DECL: case PARM_DECL: case RESULT_DECL: diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index bae21a0..0e2032c 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -3568,6 +3568,24 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack, { tree field; int count = 0; + + if (TREE_CODE (type) == COMPLEX_TYPE) + { + fieldoff_s *real_part, *img_part; + real_part = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL); + real_part->type = TREE_TYPE (type); + real_part->size = TYPE_SIZE (TREE_TYPE (type)); + real_part->offset = offset; + real_part->decl = NULL_TREE; + + img_part = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL); + img_part->type = TREE_TYPE (type); + img_part->size = TYPE_SIZE (TREE_TYPE (type)); + img_part->offset = offset + TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (type))); + img_part->decl = NULL_TREE; + + return 2; + } for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) if (TREE_CODE (field) == FIELD_DECL) |