From 2b42509f8b7bdf0a27a6687a941663380b485416 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 8 May 2020 10:24:37 +0200 Subject: [PATCH] Fix availability compute during VN DOM elimination This fixes an issue with redundant store elimination in FRE/PRE which, when invoked by the DOM elimination walk, ends up using possibly stale availability data from the RPO walk. It also fixes a missed optimization during valueization of addresses by making sure to use get_addr_base_and_unit_offset_1 which can valueize and adjusting that to also valueize ARRAY_REFs low-bound. 2020-05-08 Richard Biener * tree-ssa-sccvn.c (rpo_avail): Change type to eliminate_dom_walker *. (eliminate_with_rpo_vn): Adjust rpo_avail to make vn_valueize use the DOM walker availability. (vn_reference_fold_indirect): Use get_addr_base_and_unit_offset_1 with vn_valueize as valueization callback. (vn_reference_maybe_forwprop_address): Likewise. * tree-dfa.c (get_addr_base_and_unit_offset_1): Also valueize array_ref_low_bound. * gnat.dg/opt83.adb: New testcase. --- gcc/ChangeLog | 12 ++++++++++++ gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gnat.dg/opt83.adb | 33 +++++++++++++++++++++++++++++++++ gcc/tree-dfa.c | 32 +++++++++++++++++--------------- gcc/tree-ssa-sccvn.c | 15 ++++++++++----- 5 files changed, 76 insertions(+), 20 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/opt83.adb diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5373046116c..14605950a8b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2020-05-08 Richard Biener + + * tree-ssa-sccvn.c (rpo_avail): Change type to + eliminate_dom_walker *. + (eliminate_with_rpo_vn): Adjust rpo_avail to make vn_valueize + use the DOM walker availability. + (vn_reference_fold_indirect): Use get_addr_base_and_unit_offset_1 + with vn_valueize as valueization callback. + (vn_reference_maybe_forwprop_address): Likewise. + * tree-dfa.c (get_addr_base_and_unit_offset_1): Also valueize + array_ref_low_bound. + 2020-05-08 Jakub Jelinek PR tree-optimization/94786 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b95696f0f19..adacf69b027 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2020-05-08 Richard Biener + + * gnat.dg/opt83.adb: New testcase. + 2020-05-08 Jakub Jelinek PR tree-optimization/94786 diff --git a/gcc/testsuite/gnat.dg/opt83.adb b/gcc/testsuite/gnat.dg/opt83.adb new file mode 100644 index 00000000000..d71672f622c --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt83.adb @@ -0,0 +1,33 @@ +-- { dg-do compile } +-- { dg-options "-O2" } + +-- rpo fre3 used to loop indefinitely replacing _2 with _8 and back, +-- given MEM[(struct test__e &)_2][0]{lb: _7 sz: 16}._tag = A23s_29; +-- and an earlier _8 = &*_2[0]{lb: _7 sz: 16}. + +procedure Opt83 is + + type E is tagged record + I : Natural := 0; + end record; + + type A is array (Natural range <>) of aliased E; + + F : E; + + R : access A; + + procedure N is + begin + if R = null then + R := new A (0 .. 4); + end if; + end N; + +begin + + N; + + R (0) := F; + +end Opt83; diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index b6edc5c1352..3283d113f9b 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -806,23 +806,25 @@ get_addr_base_and_unit_offset_1 (tree exp, poly_int64_pod *poffset, if (valueize && TREE_CODE (index) == SSA_NAME) index = (*valueize) (index); + if (!poly_int_tree_p (index)) + return NULL_TREE; + low_bound = array_ref_low_bound (exp); + if (valueize + && TREE_CODE (low_bound) == SSA_NAME) + low_bound = (*valueize) (low_bound); + if (!poly_int_tree_p (low_bound)) + return NULL_TREE; + unit_size = array_ref_element_size (exp); + if (TREE_CODE (unit_size) != INTEGER_CST) + return NULL_TREE; /* If the resulting bit-offset is constant, track it. */ - if (poly_int_tree_p (index) - && (low_bound = array_ref_low_bound (exp), - poly_int_tree_p (low_bound)) - && (unit_size = array_ref_element_size (exp), - TREE_CODE (unit_size) == INTEGER_CST)) - { - poly_offset_int woffset - = wi::sext (wi::to_poly_offset (index) - - wi::to_poly_offset (low_bound), - TYPE_PRECISION (TREE_TYPE (index))); - woffset *= wi::to_offset (unit_size); - byte_offset += woffset.force_shwi (); - } - else - return NULL_TREE; + poly_offset_int woffset + = wi::sext (wi::to_poly_offset (index) + - wi::to_poly_offset (low_bound), + TYPE_PRECISION (TREE_TYPE (index))); + woffset *= wi::to_offset (unit_size); + byte_offset += woffset.force_shwi (); } break; diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 8a4af91c54e..39e99007c7e 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -1224,8 +1224,8 @@ vn_reference_fold_indirect (vec *ops, /* The only thing we have to do is from &OBJ.foo.bar add the offset from .foo.bar to the preceding MEM_REF offset and replace the address with &OBJ. */ - addr_base = get_addr_base_and_unit_offset (TREE_OPERAND (op->op0, 0), - &addr_offset); + addr_base = get_addr_base_and_unit_offset_1 (TREE_OPERAND (op->op0, 0), + &addr_offset, vn_valueize); gcc_checking_assert (addr_base && TREE_CODE (addr_base) != MEM_REF); if (addr_base != TREE_OPERAND (op->op0, 0)) { @@ -1282,8 +1282,9 @@ vn_reference_maybe_forwprop_address (vec *ops, poly_int64 addr_offset; addr = gimple_assign_rhs1 (def_stmt); - addr_base = get_addr_base_and_unit_offset (TREE_OPERAND (addr, 0), - &addr_offset); + addr_base = get_addr_base_and_unit_offset_1 (TREE_OPERAND (addr, 0), + &addr_offset, + vn_valueize); /* If that didn't work because the address isn't invariant propagate the reference tree from the address operation in case the current dereference isn't offsetted. */ @@ -2419,7 +2420,7 @@ public: }; /* Global RPO state for access from hooks. */ -static rpo_elim *rpo_avail; +static eliminate_dom_walker *rpo_avail; basic_block vn_context_bb; /* Return true if BASE1 and BASE2 can be adjusted so they have the @@ -6559,7 +6560,11 @@ eliminate_with_rpo_vn (bitmap inserted_exprs) { eliminate_dom_walker walker (CDI_DOMINATORS, inserted_exprs); + eliminate_dom_walker *saved_rpo_avail = rpo_avail; + rpo_avail = &walker; walker.walk (cfun->cfg->x_entry_block_ptr); + rpo_avail = saved_rpo_avail; + return walker.eliminate_cleanup (); } -- 2.30.2