diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-11-25 10:34:11 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-11-25 10:34:11 +0000 |
commit | 7cec548e3fe82ee6248c491c599b8b8a3f19d7ec (patch) | |
tree | 66195ff5e829f7ad937e47fa9dff36f5dc63057b | |
parent | 6441e9fd451b2ad4b86b9ca62723ef1906efd1f2 (diff) | |
download | gcc-7cec548e3fe82ee6248c491c599b8b8a3f19d7ec.tar.gz |
2008-11-25 Richard Guenther <rguenther@suse.de>
PR middle-end/38151
PR middle-end/38236
* tree-ssa-alias.c (struct alias_info): Remove written_vars.
Remove dereferenced_ptrs_store and dereferenced_ptrs_load
in favor of dereferenced_ptrs.
(init_alias_info): Adjust.
(delete_alias_info): Likewise.
(compute_flow_insensitive_aliasing): Properly
include all aliased variables.
(update_alias_info_1): Use dereferenced_ptrs.
(setup_pointers_and_addressables): Likewise.
(get_smt_for): Honor ref-all pointers and pointers with known alias
set properly.
* config/i386/i386.c (ix86_gimplify_va_arg): Use ref-all pointers.
* gcc.c-torture/execute/pr38151.c: New testcase.
* gcc.c-torture/execute/pr38236.c: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@142189 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr38151.c | 46 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr38236.c | 22 | ||||
-rw-r--r-- | gcc/tree-ssa-alias.c | 90 |
6 files changed, 130 insertions, 58 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dc991b7bf9f..148e7b2f309 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2008-11-25 Richard Guenther <rguenther@suse.de> + + PR middle-end/38151 + PR middle-end/38236 + * tree-ssa-alias.c (struct alias_info): Remove written_vars. + Remove dereferenced_ptrs_store and dereferenced_ptrs_load + in favor of dereferenced_ptrs. + (init_alias_info): Adjust. + (delete_alias_info): Likewise. + (compute_flow_insensitive_aliasing): Properly + include all aliased variables. + (update_alias_info_1): Use dereferenced_ptrs. + (setup_pointers_and_addressables): Likewise. + (get_smt_for): Honor ref-all pointers and pointers with known alias + set properly. + * config/i386/i386.c (ix86_gimplify_va_arg): Use ref-all pointers. + 2008-11-25 Uros Bizjak <ubizjak@gmail.com> PR target/38254 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index e6f00d7c8e7..8f4680db4bc 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -6753,6 +6753,8 @@ ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p, enum machine_mode mode = GET_MODE (reg); tree piece_type = lang_hooks.types.type_for_mode (mode, 1); tree addr_type = build_pointer_type (piece_type); + tree daddr_type = build_pointer_type_for_mode (piece_type, + ptr_mode, true); tree src_addr, src; int src_offset; tree dest_addr, dest; @@ -6772,8 +6774,8 @@ ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p, size_int (src_offset)); src = build_va_arg_indirect_ref (src_addr); - dest_addr = fold_convert (addr_type, addr); - dest_addr = fold_build2 (POINTER_PLUS_EXPR, addr_type, dest_addr, + dest_addr = fold_convert (daddr_type, addr); + dest_addr = fold_build2 (POINTER_PLUS_EXPR, daddr_type, dest_addr, size_int (INTVAL (XEXP (slot, 1)))); dest = build_va_arg_indirect_ref (dest_addr); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c6e9ed83bb7..860fa8c4e99 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2008-11-25 Richard Guenther <rguenther@suse.de> + + PR middle-end/38151 + PR middle-end/38236 + * gcc.c-torture/execute/pr38151.c: New testcase. + * gcc.c-torture/execute/pr38236.c: Likewise. + 2008-11-24 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> * g++.dg/eh/weak1.C: Don't xfail hppa*64*-*-*. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr38151.c b/gcc/testsuite/gcc.c-torture/execute/pr38151.c new file mode 100644 index 00000000000..113a255b15e --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr38151.c @@ -0,0 +1,46 @@ +void abort (void); + +struct S2848 +{ + unsigned int a; + _Complex int b; + struct + { + } __attribute__ ((aligned)) c; +}; + +struct S2848 s2848; + +int fails; + +void __attribute__((noinline)) +check2848va (int z, ...) +{ + struct S2848 arg; + __builtin_va_list ap; + + __builtin_va_start (ap, z); + + arg = __builtin_va_arg (ap, struct S2848); + + if (s2848.a != arg.a) + ++fails; + if (s2848.b != arg.b) + ++fails; + + __builtin_va_end (ap); +} + +int main (void) +{ + s2848.a = 4027477739U; + s2848.b = (723419448 + -218144346 * __extension__ 1i); + + check2848va (1, s2848); + + if (fails) + abort (); + + return 0; +} + diff --git a/gcc/testsuite/gcc.c-torture/execute/pr38236.c b/gcc/testsuite/gcc.c-torture/execute/pr38236.c new file mode 100644 index 00000000000..d781542c7cc --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr38236.c @@ -0,0 +1,22 @@ +struct X { int i; }; + +int __attribute__((noinline)) +foo (struct X *p, int *q, int a, int b) +{ + struct X x, y; + if (a) + p = &x; + if (b) + q = &x.i; + else + q = &y.i; + *q = 1; + return p->i; +} +extern void abort (void); +int main() +{ + if (foo((void *)0, (void *)0, 1, 1) != 1) + abort (); + return 0; +} diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 83800ed5722..6155809631d 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -188,15 +188,8 @@ struct alias_info struct alias_map_d **pointers; size_t num_pointers; - /* Variables that have been written to directly (i.e., not through a - pointer dereference). */ - struct pointer_set_t *written_vars; - - /* Pointers that have been used in an indirect store operation. */ - struct pointer_set_t *dereferenced_ptrs_store; - - /* Pointers that have been used in an indirect load operation. */ - struct pointer_set_t *dereferenced_ptrs_load; + /* Pointers that have been used in an indirect load/store operation. */ + struct pointer_set_t *dereferenced_ptrs; }; @@ -2073,9 +2066,7 @@ init_alias_info (void) ai->ssa_names_visited = sbitmap_alloc (num_ssa_names); sbitmap_zero (ai->ssa_names_visited); ai->processed_ptrs = VEC_alloc (tree, heap, 50); - ai->written_vars = pointer_set_create (); - ai->dereferenced_ptrs_store = pointer_set_create (); - ai->dereferenced_ptrs_load = pointer_set_create (); + ai->dereferenced_ptrs = pointer_set_create (); /* Clear out all memory reference stats. */ init_mem_ref_stats (); @@ -2123,9 +2114,7 @@ delete_alias_info (struct alias_info *ai) free (ai->pointers[i]); free (ai->pointers); - pointer_set_destroy (ai->written_vars); - pointer_set_destroy (ai->dereferenced_ptrs_store); - pointer_set_destroy (ai->dereferenced_ptrs_load); + pointer_set_destroy (ai->dereferenced_ptrs); free (ai); delete_mem_ref_stats (cfun); @@ -2361,23 +2350,18 @@ compute_flow_insensitive_aliasing (struct alias_info *ai) { struct alias_map_d *v_map; var_ann_t v_ann; - bool tag_stored_p, var_stored_p; v_map = ai->addressable_vars[j]; var = v_map->var; v_ann = var_ann (var); - /* Skip memory tags and variables that have never been - written to. We also need to check if the variables are - call-clobbered because they may be overwritten by - function calls. */ - tag_stored_p = pointer_set_contains (ai->written_vars, tag) - || is_call_clobbered (tag); - var_stored_p = pointer_set_contains (ai->written_vars, var) - || is_call_clobbered (var); - if (!tag_stored_p && !var_stored_p) - continue; - + /* We used to skip variables that have never been written to + if the memory tag has been never written to directly (or + either of them were call clobbered). This is not enough + though, as this misses writes through the tags aliases. + So, for correctness we need to include any aliased + variable here. */ + if (may_alias_p (p_map->var, p_map->set, var, v_map->set, false)) { /* Add VAR to TAG's may-aliases set. */ @@ -2618,13 +2602,8 @@ update_alias_info_1 (gimple stmt, struct alias_info *ai) /* ??? For always executed direct dereferences we can apply TBAA-pruning to their escape set. */ - /* If this is a store operation, mark OP as being - dereferenced to store, otherwise mark it as being - dereferenced to load. */ - if (num_stores > 0) - pointer_set_insert (ai->dereferenced_ptrs_store, var); - else - pointer_set_insert (ai->dereferenced_ptrs_load, var); + /* Mark OP as being dereferenced. */ + pointer_set_insert (ai->dereferenced_ptrs, var); /* Update the frequency estimate for all the dereferences of pointer OP. */ @@ -2649,7 +2628,7 @@ update_alias_info_1 (gimple stmt, struct alias_info *ai) if (is_gimple_call (stmt) || stmt_escape_type == ESCAPE_STORED_IN_GLOBAL) { - pointer_set_insert (ai->dereferenced_ptrs_store, var); + pointer_set_insert (ai->dereferenced_ptrs, var); pi->memory_tag_needed = 1; } } @@ -2667,17 +2646,6 @@ update_alias_info_1 (gimple stmt, struct alias_info *ai) mem_ref_stats->num_mem_stmts++; - /* Add all decls written to to the list of written variables. */ - if (gimple_has_lhs (stmt) - && TREE_CODE (gimple_get_lhs (stmt)) != SSA_NAME) - { - tree lhs = gimple_get_lhs (stmt); - while (handled_component_p (lhs)) - lhs = TREE_OPERAND (lhs, 0); - if (DECL_P (lhs)) - pointer_set_insert (ai->written_vars, lhs); - } - /* Notice that we only update memory reference stats for symbols loaded and stored by the statement if the statement does not contain pointer dereferences and it is not a call/asm site. @@ -2770,7 +2738,7 @@ setup_pointers_and_addressables (struct alias_info *ai) /* Since we don't keep track of volatile variables, assume that these pointers are used in indirect store operations. */ if (TREE_THIS_VOLATILE (var)) - pointer_set_insert (ai->dereferenced_ptrs_store, var); + pointer_set_insert (ai->dereferenced_ptrs, var); num_pointers++; } @@ -2845,8 +2813,7 @@ setup_pointers_and_addressables (struct alias_info *ai) array and create a symbol memory tag for them. */ if (POINTER_TYPE_P (TREE_TYPE (var))) { - if ((pointer_set_contains (ai->dereferenced_ptrs_store, var) - || pointer_set_contains (ai->dereferenced_ptrs_load, var))) + if (pointer_set_contains (ai->dereferenced_ptrs, var)) { tree tag, old_tag; var_ann_t t_ann; @@ -2872,11 +2839,6 @@ setup_pointers_and_addressables (struct alias_info *ai) /* Associate the tag with pointer VAR. */ set_symbol_mem_tag (var, tag); - - /* If pointer VAR has been used in a store operation, - then its memory tag must be marked as written-to. */ - if (pointer_set_contains (ai->dereferenced_ptrs_store, var)) - pointer_set_insert (ai->written_vars, tag); } else { @@ -3298,7 +3260,22 @@ get_smt_for (tree ptr, struct alias_info *ai) size_t i; tree tag; tree tag_type = TREE_TYPE (TREE_TYPE (ptr)); - alias_set_type tag_set = get_alias_set (tag_type); + alias_set_type tag_set; + + /* Get the alias set to be used for the pointed-to memory. If that + differs from what we would get from looking at the type adjust + the tag_type to void to make sure we get a proper alias set from + just looking at the SMT we create. */ + tag_set = get_alias_set (tag_type); + if (TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (ptr)) + /* This is overly conservative but we do not want to assign + restrict alias sets here (which if they are not assigned + are -2 but still "known"). */ + || DECL_POINTER_ALIAS_SET_KNOWN_P (ptr)) + { + tag_set = 0; + tag_type = void_type_node; + } /* To avoid creating unnecessary memory tags, only create one memory tag per alias set class. Note that it may be tempting to group @@ -3329,7 +3306,8 @@ get_smt_for (tree ptr, struct alias_info *ai) artificial variable representing the memory location pointed-to by PTR. */ tag = symbol_mem_tag (ptr); - if (tag == NULL_TREE) + if (tag == NULL_TREE + || tag_set != get_alias_set (tag)) tag = create_memory_tag (tag_type, true); /* Add PTR to the POINTERS array. Note that we are not interested in |