On 11/12/13 2:03 PM, Tom de Vries wrote: > On 11-11-13 14:17, Richard Biener wrote: >> On Mon, 11 Nov 2013, Tom de Vries wrote: >> >>> On 11/11/13 10:50, Richard Biener wrote: >>>> On Sat, 9 Nov 2013, Tom de Vries wrote: >>>>> Bootstrapped and regtested on x86_64. >>>>> >>>>> OK for trunk? >>>> >>>> Comments inline >>>> >>>> >>>> diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c >>>> index 98b5882..43516a7 100644 >>>> --- a/gcc/tree-ssa-tail-merge.c >>>> +++ b/gcc/tree-ssa-tail-merge.c >>>> @@ -1173,8 +1173,47 @@ gimple_equal_p (same_succ same_succ, gimple >>>> s1, gimple s2) >>>> lhs2 = gimple_get_lhs (s2); >>>> if (TREE_CODE (lhs1) != SSA_NAME >>>> && TREE_CODE (lhs2) != SSA_NAME) >>>> - return (vn_valueize (gimple_vdef (s1)) >>>> - == vn_valueize (gimple_vdef (s2))); >>>> + { >>>> + /* If the vdef is the same, it's the same statement. */ >>>> + if (vn_valueize (gimple_vdef (s1)) >>>> + == vn_valueize (gimple_vdef (s2))) >>>> + return true; >>>> + >>>> + /* If the vdef is not the same but the vuse is the same, it's >>>> not the >>>> + same stmt. */ >>>> + if (vn_valueize (gimple_vuse (s1)) >>>> + == vn_valueize (gimple_vuse (s2))) >>>> + return false; >>>> >>> >>> Richard, >>> >>>> What's the logic behind this? >>>> We want to use VN to get more "positive" >>>> results >>> >>> We can use it to get both positive and negative results faster. >> >> I can get a negative result for free: "false" ;) >> > > Richard, > > Indeed. But perhaps we could regard the question at hand from the > perspective of both compilation effect and compilation speed ;) > >> VN proves equivalency it doesn't prove non-equivalency - that's >> simply its conservative fallback. >> > > Of course. > >>>> - doing a negative early out looks suspicious to me ... >>>> >>> >>> If the vdefs are the same, the VN has concluded that the statements >>> are the >>> same. We have a positive early out. >>> >>> If the vdefs are not the same, the VN has concluded that the >>> statements are >>> different. But if the vuses are the same, the VN has concluded that the >>> statements are different because of structural difference. Which >>> means there's >>> no sense in us repeating the structural comparison. We have a >>> negative early out. >> >> Well, see above - it merely failed to prove equivalency, it didn't >> actually conclude they are different. >> > > You're right, sloppy formulation on my part. > > My question is, if VN has tried to prove equality of vdefs, and failed, > in what scenario could a structural comparison still prove them equal? > > In case the vuses are not proven equal, there's an obvious reason why > the vdefs are not proven equal, and structural comparison might indeed > prove them equal. > > But if the vuses are proven equal, that's not the reason why the vdefs > are not proven equal. In which case it's hard for me to understand how a > trivial structural check would beat VN. > > I've browsed the VN code a bit and tried to construct examples where > structural comparison beats VN, but did not manage. > > I've also done a non-bootstrap build with attached patch, and a complete > testrun, and was not able to trigger the assert. > > So if you have any hunch about such a scenario, please let me know.
I don't - just relying on the value-number for virtual operands always makes me nervous. I'm fine with the early out, it just looks odd to me (the compile-time effect should be minimal). Richard. > Thanks, > - Tom > >>> If the vdefs are not the same, the VN has concluded that the >>> statements are >>> different. But if the vuses are different, the VN may have concluded >>> that the >>> statements are different because of the different vuses. So it still >>> makes sense >>> to try structural comparison. >>> >>>> + /* If the vdef is not the same and the vuse is not the same, >>>> it might be >>>> + same stmt. */ >>>> + >>>> + /* Test for structural equality. */ >>>> + if (gimple_assign_rhs_code (s1) != gimple_assign_rhs_code (s1) >>>> >>>> s2 >>>> >>>> + || (gimple_assign_nontemporal_move_p (s1) >>>> + != gimple_assign_nontemporal_move_p (s2))) >>>> >>>> I don't think we should care (it'll be false - a later pass sets it, >>>> it's an optimization hint, not a correctness issue). More interesting >>>> would be to assert that has_volatile_ops is the same if the operands >>>> turned out to be the same. >>>> >>> >>> OK. >>> >>>> + return false; >>>> + >>>> + if (!operand_equal_p (lhs1, lhs2, 0)) >>>> + return false; >>>> + >>>> + t1 = gimple_assign_rhs1 (s1); >>>> + t2 = gimple_assign_rhs1 (s2); >>>> + if (!gimple_operand_equal_value_p (t1, t2)) >>>> + return false; >>>> + >>>> + t1 = gimple_assign_rhs2 (s1); >>>> + t2 = gimple_assign_rhs2 (s2); >>>> + if (!gimple_operand_equal_value_p (t1, t2)) >>>> + return false; >>>> + >>>> + t1 = gimple_assign_rhs3 (s1); >>>> + t2 = gimple_assign_rhs3 (s2); >>>> + if (!gimple_operand_equal_value_p (t1, t2)) >>>> + return false; >>>> >>>> for (i = 1; i < gimple_num_ops (s1); ++i) >>>> t1 = gimple_op (s1, i); >>>> ... >>>> >>>> but I think you should only compare rhs1 and thus only handle >>>> GIMPLE_ASSIGN_SINGLEs this way - the others have a SSA name >>>> lhs. >>>> >>> >>> I see. >>> >>>> That makes the whole thing just >>>> >>>> if (TREE_CODE (lhs1) != SSA_NAME >>>> && TREE_CODE (lhs2) != SSA_NAME) >>>> { >>>> if (vn_valueize (gimple_vdef (s1)) >>>> == vn_valueize (gimple_vdef (s2))) >>>> return true; >>>> return operand_equal_p (lhs1, lhs2, 0) >>>> && gimple_operand_equal_value_p (gimple_assign_rhs1 >>>> (s1), >>>> gimple_assign_rhs2 >>>> (s2)); >>>> } >>>> >>>> Ok with doing it this way. >>> >>> I'll retest and checkin like this, unless you agree about the early >>> out, which I >>> still think is a good idea, although the structural test is now much >>> smaller. >> >> I think the early out is premature. >> >> Richard. >> >