aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2010-02-11 15:38:59 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2010-02-11 15:38:59 +0000
commit91753e21c33ee0f333e529487d67a1ff60b30655 (patch)
tree677c1523c511c02cf1a26efd442c195756d993b7
parent13b7990c1a90247baa304dfa8c438d214424019f (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/cfgexpand.c3
-rw-r--r--gcc/tree-ssa-alias.c78
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,