diff options
author | Richard Guenther <rguenther@suse.de> | 2010-02-11 15:38:59 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2010-02-11 15:38:59 +0000 |
commit | 91753e21c33ee0f333e529487d67a1ff60b30655 (patch) | |
tree | 677c1523c511c02cf1a26efd442c195756d993b7 | |
parent | 13b7990c1a90247baa304dfa8c438d214424019f (diff) | |
download | gcc-91753e21c33ee0f333e529487d67a1ff60b30655.zip gcc-91753e21c33ee0f333e529487d67a1ff60b30655.tar.gz gcc-91753e21c33ee0f333e529487d67a1ff60b30655.tar.bz2 |
re PR lto/41664 (FAIL: gfortran.dg/lto/pr40725 f_lto_pr40725_0.o-f_lto_pr40725_1.o execute -O2 -fwhopr and -flto)
2010-02-11 Richard Guenther <rguenther@suse.de>
PR lto/41664
* tree-ssa-alias.c (refs_may_alias_p_1): Canonicalize
pointer-vs-decl case by swapping refs. Handle some cases
of pointer-vs-decl disambiguations more conservatively.
* cfgexpand.c (gimple_expand_cfg): Set gimple_df->in_ssa_p
to false after expanding.
From-SVN: r156699
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cfgexpand.c | 3 | ||||
-rw-r--r-- | gcc/tree-ssa-alias.c | 78 |
3 files changed, 83 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1952f78..70deed7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,14 @@ 2010-02-11 Richard Guenther <rguenther@suse.de> + PR lto/41664 + * tree-ssa-alias.c (refs_may_alias_p_1): Canonicalize + pointer-vs-decl case by swapping refs. Handle some cases + of pointer-vs-decl disambiguations more conservatively. + * cfgexpand.c (gimple_expand_cfg): Set gimple_df->in_ssa_p + to false after expanding. + +2010-02-11 Richard Guenther <rguenther@suse.de> + PR driver/43021 * gcc.c (process_command): Handle LTO file@offset case more appropriately. diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 788242c..a0d4ba5 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -3639,6 +3639,9 @@ gimple_expand_cfg (void) execute_free_datastructures (); finish_out_of_ssa (&SA); + /* We are no longer in SSA form. */ + cfun->gimple_df->in_ssa_p = false; + /* Expansion is used by optimization passes too, set maybe_hot_insn_p conservatively to true until they are all profile aware. */ pointer_map_destroy (lab_rtx_for_bb); diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 16abb4c..7b60201 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -818,6 +818,77 @@ refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p) return decl_refs_may_alias_p (base1, offset1, max_size1, base2, offset2, max_size2); + ind1_p = INDIRECT_REF_P (base1); + ind2_p = INDIRECT_REF_P (base2); + /* Canonicalize the pointer-vs-decl case. */ + if (ind1_p && var2_p) + { + HOST_WIDE_INT tmp1; + tree tmp2; + ao_ref *tmp3; + tmp1 = offset1; offset1 = offset2; offset2 = tmp1; + tmp1 = max_size1; max_size1 = max_size2; max_size2 = tmp1; + tmp2 = base1; base1 = base2; base2 = tmp2; + tmp3 = ref1; ref1 = ref2; ref2 = tmp3; + var1_p = true; + ind1_p = false; + var2_p = false; + ind2_p = true; + } + + /* If we are about to disambiguate pointer-vs-decl try harder to + see must-aliases and give leeway to some invalid cases. + This covers a pretty minimal set of cases only and does not + when called from the RTL oracle. It handles cases like + + int i = 1; + return *(float *)&i; + + and also fixes gfortran.dg/lto/pr40725. */ + if (var1_p && ind2_p + && cfun + && gimple_in_ssa_p (cfun) + && TREE_CODE (TREE_OPERAND (base2, 0)) == SSA_NAME) + { + gimple def_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (base2, 0)); + while (is_gimple_assign (def_stmt) + && (gimple_assign_rhs_code (def_stmt) == SSA_NAME + || CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))) + { + tree rhs = gimple_assign_rhs1 (def_stmt); + HOST_WIDE_INT offset, size, max_size; + + /* Look through SSA name copies and pointer conversions. */ + if (TREE_CODE (rhs) == SSA_NAME + && POINTER_TYPE_P (TREE_TYPE (rhs))) + { + def_stmt = SSA_NAME_DEF_STMT (rhs); + continue; + } + if (TREE_CODE (rhs) != ADDR_EXPR) + break; + + /* If the pointer is defined as an address based on a decl + use plain offset disambiguation and ignore TBAA. */ + rhs = TREE_OPERAND (rhs, 0); + rhs = get_ref_base_and_extent (rhs, &offset, &size, &max_size); + if (SSA_VAR_P (rhs)) + { + base2 = rhs; + offset2 += offset; + if (size != max_size + || max_size == -1) + max_size2 = -1; + return decl_refs_may_alias_p (base1, offset1, max_size1, + base2, offset2, max_size2); + } + + /* Do not continue looking through &p->x to limit time + complexity. */ + break; + } + } + /* First defer to TBAA if possible. */ if (tbaa_p && flag_strict_aliasing @@ -833,19 +904,12 @@ refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p) return true; /* Dispatch to the pointer-vs-decl or pointer-vs-pointer disambiguators. */ - ind1_p = INDIRECT_REF_P (base1); - ind2_p = INDIRECT_REF_P (base2); set = tbaa_p ? -1 : 0; if (var1_p && ind2_p) return indirect_ref_may_alias_decl_p (ref2->ref, TREE_OPERAND (base2, 0), offset2, max_size2, set, ref1->ref, base1, offset1, max_size1, set); - else if (ind1_p && var2_p) - return indirect_ref_may_alias_decl_p (ref1->ref, TREE_OPERAND (base1, 0), - offset1, max_size1, set, - ref2->ref, base2, - offset2, max_size2, set); else if (ind1_p && ind2_p) return indirect_refs_may_alias_p (ref1->ref, TREE_OPERAND (base1, 0), offset1, max_size1, set, |