[PATCH] Fix for PR52009 - Another missed tail merging opportunity

Tom de Vries Tom_deVries@mentor.com
Wed Jul 4 18:07:00 GMT 2012


On 31/01/12 22:07, Tom de Vries wrote:
> On 31/01/12 22:05, Tom de Vries wrote:
>> Richard,
>>
> 
> Sorry, with patch this time.
> 
>> this patch fixes PR52009.
>>
>> Consider this test-case:
>> ...
>> int z;
>>
>> void
>> foo (int y)
>> {
>>   if (y == 6)
>>     z = 5;
>>   else
>>     z = 5;
>> }
>> ...
>>
>> Currently, compiling with -O2 gives us this representation at pr51879-7.c.094t.pre:
>> ...
>>   # BLOCK 3 freq:1991
>>   # PRED: 2 [19.9%]  (true,exec)
>>   # .MEMD.1710_4 = VDEF <.MEMD.1710_3(D)>
>>   zD.1702 = 5;
>>   goto <bb 5>;
>>   # SUCC: 5 [100.0%]  (fallthru,exec)
>>
>>   # BLOCK 4 freq:8009
>>   # PRED: 2 [80.1%]  (false,exec)
>>   # .MEMD.1710_5 = VDEF <.MEMD.1710_3(D)>
>>   zD.1702 = 5;
>>   # SUCC: 5 [100.0%]  (fallthru,exec)
>>
>>   # BLOCK 5 freq:10000
>>   # PRED: 3 [100.0%]  (fallthru,exec) 4 [100.0%]  (fallthru,exec)
>>   # .MEMD.1710_2 = PHI <.MEMD.1710_4(3), .MEMD.1710_5(4)>
>>   # VUSE <.MEMD.1710_2>
>>   return;
>> ...
>>
>> Blocks 3 and 4 are not tail-merged.
>>
>> The patch allows the example to be tail-merged by:
>> - value numbering .MEMD.1710_4 and .MEMD.1710_5 equal
>> - comparing gimple_vdef value numbers for assignments during tail-merge
>>
>> Bootstrapped and reg-tested on x86_64.
>>
>> OK for stage1?
>>

Richard,

I did some trivial changes such that the patch is applicable again to trunk, and
added a test-case, which you suggested in
http://gcc.gnu.org/ml/gcc-patches/2012-05/msg00220.html.

The test-case handles the case of 2 identical calls assigning to different
deferenced pointers, where the pointers are value-numbered the same:
...
void bar (int c, int *p)
{
  int *q = p;

  if (c)
    *p = foo ();
  else
    *q = foo ();
}
...

The representation before pre looks like this:
...
  # BLOCK 3 freq:3900
  # PRED: 2 [39.0%]  (true,exec)
  # .MEMD.1724_8 = VDEF <.MEMD.1724_7(D)>
  # USE = nonlocal
  # CLB = nonlocal
  D.1721_4 = fooD.1712 ();
  # .MEMD.1724_9 = VDEF <.MEMD.1724_8>
  *pD.1714_1(D) = D.1721_4;
  goto <bb 5>;
  # SUCC: 5 [100.0%]  (fallthru,exec)

  # BLOCK 4 freq:6100
  # PRED: 2 [61.0%]  (false,exec)
  # .MEMD.1724_10 = VDEF <.MEMD.1724_7(D)>
  # USE = nonlocal
  # CLB = nonlocal
  D.1723_5 = fooD.1712 ();
  # .MEMD.1724_11 = VDEF <.MEMD.1724_10>
  *qD.1717_2 = D.1723_5;
  # SUCC: 5 [100.0%]  (fallthru,exec)
...

In pre, we're already value numbering the result and vdef of the calls the same,
and the pointers the same:
...
Value numbers:
q_2 = p_1(D)
D.1723_5 = D.1721_4
.MEM_10 = .MEM_8
...

But not the vdefs of the stores. This patch implements that, and allows the
blocks to be merged.

ok for trunk?

Thanks,
- Tom

2012-07-04  Tom de Vries  <tom@codesourcery.com>

	PR tree-optimization/52009
	* tree-ssa-tail-merge.c (gimple_equal_p): For GIMPLE_ASSIGN, compare
	value numbers of gimple_vdef.
	* tree-ssa-sccvn.h (vn_reference_insert): Add vdef parameter to
	prototype.
	* tree-ssa-sccvn.c (copy_reference_ops_from_ref): Handle MODIFY_EXPR.
	(vn_reference_insert): Add and handle vdef parameter.
	(visit_reference_op_load): Add argument to vn_reference_insert call.
	(visit_reference_op_store): Find value number of vdef of store.  Insert
	value number of vdef of store.

	* gcc.dg/pr51879-7.c: New test.
	* gcc.dg/pr51879-18.c: New test.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pr52009.patch
Type: text/x-patch
Size: 6670 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20120704/e804b67c/attachment.bin>


More information about the Gcc-patches mailing list