[PATCH] D24805: [GVNSink] Initial GVNSink prototype

James Molloy via llvm-commits llvm-commits at lists.llvm.org
Tue May 23 07:10:16 PDT 2017


Hi,

Firstly, overall I think perfection shouldn't stand in the way of progress and that GVNSink is a good improvement on the really bad bisimulation algorithm in SimplifyCFG. Do you have any objections to it going in-tree and I can work on improving/rewriting the algorithm there, after I remove the old SimplifyCFG algorithm?

I'm afraid I don't fully follow you. What compounds this is that you've referred to this (inverted or post value numbering) being in the literature somewhere, but I've totally failed to find it. Do you have any starting pointers?

Consider the following example, which is one of the simple motivating testcases for the creation of GVNSink (it doesn't show all the features of GVNSink by a long way, but it does illustrate a problem):

bb1:
  x1 = load %p
  x2 = add x1, %g
  x3 = add x2, 5
  x4 = add x3, %g2
  store x4, %p
  goto bb3

bb2:
  y1 = load %p
  y2 = add y1, %g
  y3 = add y2, 42
  y4 = add y3, %g2
  store y4, %p
  goto bb3

In this example all instructions can be sunk to bb3 with just one phi(5, 42). I'm trying to understand how your suggestion would work. You said:

"(in particular, you will create a phi for any value with two different leaders at a join point you must pass to sink it. If you calculate this properly, and in topo order of expressions, such that you process operands before things that use them, you can calculate the number of phis you would insert in O(N) time overall)"

My difficulty is that I can't think of a value numbering function that wouldn't diverge at {x3, y3}. Consider a "normal" value numbering in which VN[x] == VN[y] iff congruent(x, y):


bb1:
  x1 = load %p     [VN=1]
  x2 = add x1, %g  [VN=2]
  x3 = add x2, 5   [VN=3]
  x4 = add x3, %g2 [VN=4]
  store x4, %p     [VN=5]
  goto bb3

bb2:
  y1 = load %p     [VN=1]
  y2 = add y1, %g  [VN=2]
  y3 = add y2, 42  [VN=6]  <-- 42 != 5, so VN[y3] != VN[x3]
  y4 = add y3, %g2 [VN=7]
  store y4, %p     [VN=8]  <-- value numbers have diverged
  goto bb3

Now consider an inverse value numbering in which VN[x] == VN[y] => x or y's uses can be replaced with phi(x, y):

bb1:
  x1 = load %p     [VN=7]  <-- value numbers have diverged
  x2 = add x1, %g  [VN=6]  <-- x2 cannot be used the same as y2; different constants get added
  x3 = add x2, 5   [VN=3]  <-- x3 is used the same as y3
  x4 = add x3, %g2 [VN=2]
  store x4, %p     [VN=1]
  goto bb3

bb2:
  y1 = load %p     [VN=5]
  y2 = add y1, %g  [VN=4]
  y3 = add y2, 42  [VN=3]
  y4 = add y3, %g2 [VN=2]
  store y4, %p     [VN=1]
  goto bb3

Both value numberings notice the similarity of only half the sinkable instructions.

The way I get around this in GVNSink is to define VN[x] as an *optimistic* function that only takes into account the opcodes and number of uses. This allows it to number x2 and y2 the same, even though they could not actually replace each other. The value numbering is used purely as a tool to narrow the search space - bisimulation (or n-simulation!) takes over after that to ensure validity.

The way I'm thinking about this problem, there is surely no such value numbering function that will indicate when a PHI is needed and will not diverge at that point. Therefore, I must be thinking about the problem differently (wrongly) to you.

Could you please enlighten me or maybe point me at papers?

Cheers, and apologies for the slowness in picking this up.

James
On 22 May 2017, at 17:46, Daniel Berlin <dberlin at dberlin.org<mailto:dberlin at dberlin.org>> wrote:



On Mon, May 22, 2017 at 8:41 AM, James Molloy <James.Molloy at arm.com<mailto:James.Molloy at arm.com>> wrote:
Hi,

Thanks for the quick reply; this is a very helpful and constructive discussion :)

Happy to help :)


The oversimplification and repetition below is for my own understanding and so that I can better understand your replies, as you know this subject far better than I.

A: store 1
B: store 2
C: store 3
D:

I understand that in a classical sinking algorithm we'd want to walk backwards:
  1) Sink 'store 3' from C to D
  2) Sink 'store 2' from B to D
  3) Sink 'store 1' from A to D

A key to this working is that each instruction, when considered, was sunk as far as it could be. If we had added the restriction that an instruction could only be sunk to its immediate successor block, that algorithm would have taken three iterations to reach a fixpoint.
Yes


GVNSink can (at the moment at least) only sink instructions from a block into its immediate successor. This is what allows it to model accurately enough how many PHIs it is going to create and whether sinking is actually worthwhile (and how much sinking)

How much is the former, and how much is the later?

The number of phis you can create is calculable ahead of time in O(N) time for all operands, and related the availability of values
(in particular, you will create a phi for any value with two different leaders at a join point you must pass to sink it. If you calculate this properly, and in topo order of expressions, such that you process operands before things that use them, you can calculate the number of phis you would insert in O(N) time overall)


. I don't believe it would be able to handle all the cases it currently does if it didn't have this restriction (but would be able to handle other cases that it currently can't, so I see that very much as an enhancement I'd like to add later).

I actually don't buy this, fwiw.
It's entirely possible to calculate all the hypothetical insertion points ahead of time, and figure out which make sense from a cost perspective.
There are sinking (and PRE) algorithms that do this.
You could do exactly the same cases you do now.


Now, whether you want that complexity is a different question :)


IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170523/80af540b/attachment.html>


More information about the llvm-commits mailing list