PING.

Thanks,
Martin

On 07/20/2015 09:51 AM, Martin Liška wrote:
> On 07/16/2015 01:03 PM, Martin Liška wrote:
>> On 07/09/2015 06:24 PM, Jeff Law wrote:
>>> On 07/09/2015 07:56 AM, mliska wrote:
>>>> gcc/ChangeLog:
>>>>
>>>> 2015-07-09  Martin Liska  <mli...@suse.cz>
>>>>
>>>>     * dbgcnt.def: Add new debug counter.
>>>>     * ipa-icf-gimple.c (func_checker::compare_ssa_name): Add flag
>>>>     for strict mode.
>>>>     (func_checker::compare_memory_operand): Likewise.
>>>>     (func_checker::compare_cst_or_decl): Handle if we are in
>>>>     tail_merge_mode.
>>>>     (func_checker::compare_operand): Pass strict flag properly.
>>>>     (func_checker::stmt_local_def): New function.
>>>>     (func_checker::compare_phi_node): Move from sem_function class.
>>>>     (func_checker::compare_bb_tail_merge): New function.
>>>>     (func_checker::compare_bb): Improve STMT iteration.
>>>>     (func_checker::compare_gimple_call): Pass strict flag.
>>>>     (func_checker::compare_gimple_assign): Likewise.
>>>>     (func_checker::compare_gimple_label): Remove unused flag.
>>>>     (ssa_names_set): New class.
>>>>     (ssa_names_set::build): New function.
>>>>     * ipa-icf-gimple.h (func_checker::gsi_next_nonlocal): New
>>>>     function.
>>>>     (ssa_names_set::contains): New function.
>>>>     (ssa_names_set::add): Likewise.
>>>>     * ipa-icf.c (sem_function::equals_private): Use transformed
>>>>     function.
>>>>     (sem_function::compare_phi_node): Move to func_checker class.
>>>>     * ipa-icf.h: Add new declarations.
>>>>     * tree-ssa-tail-merge.c (check_edges_correspondence): New
>>>>     function.
>>>>     (find_duplicate): Add usage of IPA ICF gimple infrastructure.
>>>>     (find_clusters_1): Pass new sem_function argument.
>>>>     (find_clusters): Likewise.
>>>>     (tail_merge_optimize): Call IPA ICF comparison machinery.
>>> So a general question.  We're passing in STRICT to several routines, which 
>>> is fine.  But then we're also checking M_TAIL_MERGE_MODE.  What's the 
>>> difference between the two?  Can they be unified?
>>
>> Hello.
>>
>> I would say that STRICT is a bit generic mechanism that was introduced some 
>> time before. It's e.g. used for checking of THIS arguments for methods and 
>> make checking
>> more sensitive in situations that are somehow special.
>>
>> The newly added state is orthogonal to the previous one.
>>
>>>
>>>
>>>>
>>>> -/* Verifies that trees T1 and T2 are equivalent from perspective of ICF.  
>>>> */
>>>> +/* Verifies that trees T1 and T2 are equivalent from perspective of ICF.
>>>> +   If STRICT flag is true, versions must match strictly.  */
>>>>
>>>>   bool
>>>> -func_checker::compare_ssa_name (tree t1, tree t2)
>>>> +func_checker::compare_ssa_name (tree t1, tree t2, bool strict)
>>> This (and other) functions would seem to be used more than just ICF at this 
>>> point.  A pass over the comments to update them as appropriate would be 
>>> appreciated.
>>>
>>>> @@ -626,6 +648,136 @@ func_checker::parse_labels (sem_bb *bb)
>>>>       }
>>>>   }
>>>>
>>>> +/* Return true if gimple STMT is just a local difinition in a
>>>> +   basic block.  Used SSA names are contained in SSA_NAMES_SET.  */
>>> s/difinition/definition/
>>
>> Thanks.
>>
>>>
>>> I didn't find this comment particularly useful in understanding what this 
>>> function does.  AFAICT the function looks as the uses of the LHS of STMT 
>>> and verifies they're all in the same block as STMT, right?
>>>
>>> It also verifies that the none of the operands within STMT are part of 
>>> SSA_NAMES_SET.
>>>
>>> What role do those properties play in the meaning of "local definition"?
>>
>> I tried to explain it more deeply what's the purpose of this function.
>>
>>>
>>>
>>>
>>>
>>>> @@ -1037,4 +1205,60 @@ func_checker::compare_gimple_asm (const gasm *g1, 
>>>> const gasm *g2)
>>>>     return true;
>>>>   }
>>>>
>>>> +void
>>>> +ssa_names_set::build (basic_block bb)
>>> Needs a function comment.  What are the "important" names we're collecting 
>>> here?
>>>
>>> Is a single forward and backward pass really sufficient to find all the 
>>> important names?
>>>
>>> In the backward pass, do you have to consider things like ASMs?  I guess 
>>> it's difficult to understand what you need to look at because it's not 
>>> entirely clear the set of SSA_NAMEs you're building.
>>>
>>>
>>>
>>>> @@ -149,12 +153,20 @@ public:
>>>>        mapping between basic blocks and labels.  */
>>>>     void parse_labels (sem_bb *bb);
>>>>
>>>> +  /* For given basic blocks BB1 and BB2 (from functions FUNC1 and FUNC),
>>>> +     true value is returned if phi nodes are semantically
>>>> +     equivalent in these blocks.  */
>>>> +  bool compare_phi_node (sem_bb *sem_bb1, sem_bb *sem_bb2);
>>> Presumably in the case of tail merging, FUNC1 and FUNC will be the same :-)
>>
>> Yes, the function is not called from tail-merge pass.
>>
>>>
>>>
>>>>     /* Verifies that trees T1 and T2 are equivalent from perspective of 
>>>> ICF.  */
>>>> -  bool compare_ssa_name (tree t1, tree t2);
>>>> +  bool compare_ssa_name (tree t1, tree t2, bool strict = true);
>>>>
>>>>     /* Verification function for edges E1 and E2.  */
>>>>     bool compare_edge (edge e1, edge e2);
>>>> @@ -204,7 +216,7 @@ public:
>>>>     bool compare_tree_ssa_label (tree t1, tree t2);
>>>>
>>>>     /* Function compare for equality given memory operands T1 and T2.  */
>>>> -  bool compare_memory_operand (tree t1, tree t2);
>>>> +  bool compare_memory_operand (tree t1, tree t2, bool strict = true);
>>>>
>>>>     /* Function compare for equality given trees T1 and T2 which
>>>>        can be either a constant or a declaration type.  */
>>>> @@ -213,7 +225,7 @@ public:
>>>>     /* Function responsible for comparison of various operands T1 and T2.
>>>>        If these components, from functions FUNC1 and FUNC2, are equal, true
>>>>        is returned.  */
>>>> -  bool compare_operand (tree t1, tree t2);
>>>> +  bool compare_operand (tree t1, tree t2, bool strict = false);
>>> Is the default value for the parameter really needed in these methods? Why 
>>> not go ahead and update the callers, I don't think we have that many right 
>>> now.
>>
>> I've just grepped errors and it's more than 20 occurrences, so I hope it 
>> clarifies
>> the usage of implicit value of the function.
>>
>>>
>>>>
>>>>     /* Compares two tree list operands T1 and T2 and returns true if these
>>>>        two trees are semantically equivalent.  */
>>>> @@ -237,6 +249,13 @@ public:
>>>>        first parameter of a function.  */
>>>>     static bool compatible_types_p (tree t1, tree t2);
>>>>
>>>> +  /* Return true if gimple STMT is just a local difinition in a
>>>> +     basic block.  Used SSA names are contained in SSA_NAMES_SET.  */
>>>> +  static bool stmt_local_def (gimple stmt, ssa_names_set *ssa_names_set);
>>> s/difinition/definition/
>>> As with the implementation, I think the comment needs some clarification.
>>>
>>>>  +/* SSA NAMES set.  */
>>>> +class ssa_names_set
>>> So what names are in this set?  Ie, what is the ::build method searching 
>>> for?
>>>
>>>
>>>> diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
>>>> index 018a966..b8632d7 100644
>>>> --- a/gcc/tree-ssa-tail-merge.c
>>>> +++ b/gcc/tree-ssa-tail-merge.c
>>>> @@ -187,6 +187,7 @@ along with GCC; see the file COPYING3.  If not see
>>>>
>>>>   #include "config.h"
>>>>   #include "system.h"
>>>> +#include <list>
>>>>   #include "coretypes.h"
>>>>   #include "backend.h"
>>>>   #include "tree.h"
>>> I think Andrew has defined an ordering for the initial include files. I 
>>> think you've #included <list> in the wrong place.  Can it be moved down?
>>
>> Sure.
>>
>>>
>>>> +
>>>> +using namespace ipa_icf;
>>>> +using namespace ipa_icf_gimple;
>>> Is this wise?  Does it significantly help with conciseness within the tail 
>>> merging pass where it wants things ipa-icf and ipa-icf-gimple?
>>>
>>> I'm not objecting at this point, I want to hear your thoughts.
>>
>> I must agree with you, as I've started using both namespaces in tree-tail 
>> merge pass,
>> it makes not much sense anymore. I suggest to come up with a namespace that 
>> will
>> encapsulate 'identical code folding'-related stuff. What about:
>>
>> namespace icf
>>
>> ?
>>
>>>
>>>
>>>>
>>>>   /* Describes a group of bbs with the same successors.  The successor bbs 
>>>> are
>>>>      cached in succs, and the successor edge flags are cached in 
>>>> succ_flags.
>>>> @@ -1220,17 +1231,48 @@ gsi_advance_bw_nondebug_nonlocal 
>>>> (gimple_stmt_iterator *gsi, tree *vuse,
>>>>       }
>>>>   }
>>>>
>>>> +static bool
>>>> +check_edges_correspondence (basic_block bb1, basic_block bb2)
>>> Needs a function comment.
>>>
>>>
>>>> +{
>>>> +  edge e1, e2;
>>>> +  edge_iterator ei2 = ei_start (bb2->succs);
>>>> +
>>>> +  for (edge_iterator ei1 = ei_start (bb1->succs); ei_cond (ei1, &e1);
>>>> +       ei_next (&ei1))
>>>> +    {
>>>> +      ei_cond (ei2, &e2);
>>>> +
>>>> +      if (e1->dest->index != e2->dest->index ||
>>>> +      (e1->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE))
>>>> +      != (e2->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
>>>> +    return false;
>>> Formatting looks wrong in that conditional.
>>>
>>>> @@ -1265,11 +1307,29 @@ find_duplicate (same_succ same_succ, basic_block 
>>>> bb1, basic_block bb2)
>>>>     if (vuse_escaped && vuse1 != vuse2)
>>>>       return;
>>>>
>>>> -  if (dump_file)
>>>> -    fprintf (dump_file, "find_duplicates: <bb %d> duplicate of <bb %d>\n",
>>>> +  if (!icf_result && dump_file)
>>>> +    fprintf (dump_file,
>>>> +         "missed merge optimization: <bb %d> duplicate of <bb %d>\n",
>>>>            bb1->index, bb2->index);
>>> So I realize this goes away in the #2 patch.  But I'm curious how often it 
>>> triggered and if there were any interesting patterns when the old tail 
>>> merging triggered by the version utilizing ICF didn't or vice-versa.
>>>
>>> You mentioned posting some before/after results, but I haven't seen them 
>>> yet.
>>>
>>> I'd like to do another pass over these changes, so if you could repost 
>>> after the cleanups noted above, it'd be appreciated.
>>>
>>> Jeff
>>>
>>>
>>
>> I decided to come up with a single patch, mainly because Richi pointed out 
>> that we should create a new tree pass and
>> it makes sense to do it in a single commit. In last patch of the previous 
>> series, I modified some UBSAN tests, but proper
>> fix would be to ignore merging of UBSAN_* calls (as suggested in 
>> corresponding emails).
>>
>> Following patch can survive bootstrap on x86_64-linux-pc and 
>> ppc64le-linux-pc and regression tests.
>>
>> There are sizes of binaries before and after the patch:
>>
>> INKSCAPE:
>> before: 15626296 B
>> after: 15622200 B
>>
>> Firefox:
>> before: 130390352 B
>> after: 130379744 B 
>> diff: 10608 B
>>
>> Thanks,
>> Martin
>>
>>
> 
> Hello.
> 
> This is v3 of the patch sent last week. I've noticed couple of regressions 
> that are fixed in the patch,
> updated numbers are as follows:
> 
> INKSCAPE:
> after_v3: 15618104 B (8192B smaller than original)
> 
> FIREFOX:
> after_v3: 130368208 B (22144B smaller than original)
> 
> Thanks for review,
> Martin
> 

Reply via email to