[PATCH] D26224: NewGVN

Daniel Berlin via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 12 19:09:37 PST 2016


There are about 5 starting since 2007.  You have to be careful, most focus
on finding "equivalence among variables in the program".

IE they are trying to find equivalence among *variables* and not among the
set of *subexpressions in the program*.

That is, they are useful for redundancy elimination. The will tell you
"this instruction and that instruction are equal".

But you can imagine sub-expressions that, if they were reassociated/forward
propagated, would be equivalent.

The one i've seen implemented for real was "An Efficient SSA-Based
Algorithm for Complete Global Value Numbering" by Nie and Cheng.

There is also, for example,
http://link.springer.com/chapter/10.1007/978-3-319-26529-2_4

(note that a lot of this algorithm parallels the code i wrote for gcc for
value based PRE, so it would be pretty easy to port)


On Mon, Dec 12, 2016 at 6:20 PM, Davide Italiano <dccitaliano at gmail.com>
wrote:

> On Mon, Dec 12, 2016 at 6:18 PM, Davide Italiano <dccitaliano at gmail.com>
> wrote:
> > On Mon, Dec 12, 2016 at 5:52 PM, Daniel Berlin via Phabricator
> > <reviews at reviews.llvm.org> wrote:
> >> dberlin added inline comments.
> >>
> >>
> >> ================
> >> Comment at: lib/Transforms/Scalar/NewGVN.cpp:10
> >> +/// \file
> >> +/// This file implements the new LLVM's Global Value Numbering pass.
> >> +///
> >> ----------------
> >> davide wrote:
> >>> silvas wrote:
> >>> > This file comment needs to be signficantly expanded. Remember, lots
> of people looking at this class might be e.g. people taking a compiler
> class that want to look at a "real" GVN implementation. Let's make sure
> come away impressed so that they will want to join LLVM!
> >>> >
> >>> > At the very least, some citations for the relevant paper and stuff,
> along with summary of which exact variant of the algorithm are implemented
> would be good. Also, I think the high-level idea of GVN is simple enough
> that a high-level from-scratch description would be appropriate. I can help
> with writing this if you want.
> >>> >
> >>> > In theory, we can expand this later, but when have you seen a commit
> improving a file-level comment? The only one I remember was in response to
> post-commit review asking for an improved file-level comment. So getting it
> right the first time is actually pretty important.
> >>> I agree. Tried to expand it a bit.
> >>
> >>
> >> I'm happy to describe the sparse predicated algorithm a bit if you want
> to add it.  I'll touch on the predication/etc bits when we add them.
> >>
> >> Traditional GVN algorithms fall into two categories: Congruence
> partitioning and Hash based.
> >>
> >> Hash based GVN's hash the operation performed by an instruction in some
> fashion, and look it up in a hash table.  Anything that hashes the same and
> is otherwise "congruent" is considered equal.  A hash based value numbering
> is optimistic if it is assumes that everything not in the table is
> congruent to everything else, and pessimistic if it is assumes everything
> not in the table is not congruent to everything else.
> >>
> >> Congruence partitioning based GVN's start with every value in a single
> partition, and split the partition as they discover values that are not
> equal.
> >>
> >> Optimistic hash based GVN and congruence partitioning GVN will discover
> the same set of congruences.
> >>
> >> Most compilers nowadays use optimistic hash based approaches.  The
> downside to optimistic hash based value numbering is that it requires
> reprocessing the entire routine again and again until the hashtables stops
> changing.  This is because value dependences are not tracked well enough to
> know what must be reprocessed, and values can be involved in cycles
> (meaning there is no perfect order in which you can process the function to
> get a correct result).   This makes these algorithms non-sparse. There are
> refinements to these algorithms, such as SCC based value numbering, which
> only requires iterating SCC's of the SSA graph, but most compilers use the
> hash table approach.
> >>
> >> By contrast, the algorithm is more like the sparse conditional constant
> propagation algorithm, and uses a worklist of instructions to process.
>  Dependencies between values and instructions are tracked finely enough
> (through the CongruenceClass structure) that when the value an operation
> has changes, we add the possibly dependent instructions to the worklist and
> keep going.
> >>
> >> Memory locations s also value numbered by this algorithm.  For memory,
> the goal of the algorithm is to discover the values stored at various
> memory locations (instead of just what loads are equivalent).  Because of
> this loads and stores are value numbered together (while they are different
> expression classes, the hash ensures this occurs).    MemorySSA is used to
> value number memory state.
> >>
> >> To give a concrete example, given:
> >> 1 = MemoryDef(0)
> >> store %a, %ptr
> >>
> >> and
> >>
> >> MemoryUse (1)
> >> load %ptr
> >>
> >> These will be value numbered into the same congruence class, as the
> memory is the same location with the same value.
> >>
> >> This also enables the algorithm to discover equivalences that alias
> analysis cannot easily do.
> >>
> >> A trivial example:
> >>
> >> 1= MemoryDef(0)
> >> store %a, %ptr
> >> MemoryUse(1)
> >> load %ptr
> >> 2 = MemoryDef(1)
> >> store %a, %ptr
> >> MemoryUse(2)
> >> load %ptr
> >>
> >>
> >> These loads are equivalent, but a simple value numbering will not
> discover this.
> >>
> >> The algorithm we use will discover that the stores store the same
> value, and thus will say that 1 and 2 are equivalent memory states.
> >>
> >> It will then value number
> >> MemoryUse(2)
> >> load %ptr
> >>
> >> as if it was
> >> MemoryUse(1)
> >> load %ptr
> >>
> >> This enables the algorithm to discover fairly advanced (and even
> cyclic) equivalences between memory locations, much as it will do for
> scalars.
> >>
> >> The algorithm used also performs unreachable code elimination/etc,
> similar to how sparse conditional constant propagation works. It
> optimistically assumes edges are unreachable until proven otherwise, and
> ignores unreachable values when value numbering phi nodes to create a
> maximal answer to value equivalence.
> >>
> >> In addition to the above this algorithm supports forward propagation,
> global reassociation, and predication.
> >>
> >>
> >
> > Wow, thanks. Maybe we can add this to the web documentation (and keep
> > the comment in the file slightly shorter with a pointer to it).
>
> While we discuss GVN algorithms, not sure if we discussed this in
> person or you were talking about on the mailing lists/bugzilla but I
> seem to remember you pointing out a complete GVN algorithm very very
> new (from 2013). Were/are you referring to the extension of Necula's
> poly GVN algorithm (circa 2006), i.e.
> https://arxiv.org/pdf/1302.6325.pdf ?
>
> Thanks!
>
> --
> Davide
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161212/cccdc713/attachment-0001.html>


More information about the llvm-commits mailing list