[PATCH] D28934: Write a new SSAUpdater
Daniel Berlin via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 20 19:59:01 PST 2017
dberlin added a comment.
In https://reviews.llvm.org/D28934#652243, @MatzeB wrote:
> In https://reviews.llvm.org/D28934#652235, @dberlin wrote:
> > As for what's public:
> > The paper comments that for incremental updates, you want readVariableBeforeDef. This is equivalence to getValueAtMiddleOfBlock, which we make public in SSAUpdater.
> > The paper's API is actually identical to SSAUpdater's old API circa 2010, with the functions renamed.
> > The only difference is the more advanced phi placement algorithms.
> > I think Bob even has most of the marker algorithm right at one point if you go back through the file's history.
> > I think if we keep going down this route i would change the API.
> > Users shouldn't generally have to care where in the block they are.
> > The real problem on this front is loops.
> > Given:
> > main:
> > def(a)
> > goto loop
> > loop:
> > use (a)
> > def (a)
> > goto loop or somewhere else
> > For loop, you need
> > 1. To call writeVariable of both defs so it's visible to the algorithm, otherwise, it will not get the value over the backedge.
> > 2. But ask about the version before the def, because that's where the use is.
> Yep, however that soon breaks down as soon as you have more than 1 definition in a block so there isn't a single before/after def anymore.
> Just reviewing the libfirm SSA updater, we indeed first introduced all defs to the algorithm (picking the latest one if there are multiple) and then go over all defs/uses in a block from top to bottom.
There is a better way, IMHO, to do this,if you have the set of all defs/uses at once (which in LLVM, you can get easily), and it's fixed, by using a variant of traditional renaming:
The traditional SSA renaming algorithm is O(B+I) because it walks all instructions in dominator order by walking the blocks in the dom tree.
The only reason it does this is to push/pop the renaming stack in the right order.
But it's not actually necessary to walk the blocks at all to get the right ordering of the renaming stack.
You can get the dfs completion numbers of the dominator block for each def/use (and, if they aren't the only def/use in the block, use orderedbasicblock or something to get a local numbering. A lot of passes i work on have the local numbering lying around anyway).
Sort the defs/uses by the dfs completion numbers then the local numbers.
For each def/use:
<stack consists of member, domnodedfsin, domnodedfsout>
sync rename stack to dominate current DFS scope of def/use by popping until member dfsin/out is contained by dom node.
push onto rename stack if you have a def
if stack is empty, and you are staring at a use, it's undef
any use is defined by top of stack.
(i'm going to blog this algorithm at some point, because i don't see it really described in any paper, but it's O(def+uses) if you have a local numbering around.)
This is if you've inserted phi nodes using some other algorithm, of course.
You can integrate phi node insertion into this algorithm (for starters, IIRC, you only ever have to insert a phi node if stack.size() > 1) by integrating the paper's algorithm into this one.
I use a variant of this algorithm to do value numbering elimination in O(number of things equal to each other) instead of O(I) like the standard algorithms.
Its also used to do renaming for copy insertion here: here:https://github.com/dberlin/llvm-gvn-rewrite/blob/newgvn-predicateinfo/lib/Transforms/Utils/PredicateInfo.cpp
(in that case, you can even play the marker algorithm style game and only insert a copy once you see a use that will use it. This avoids having to compute liveness just to avoid useless insertions)
>> I think this should all be hidden, and orderedbb or something used to locate the relative position of the use to the defs.
> Yep, some notion of ordering is necessary to get multiple defs/uses in a block "right", finding a way to hide it would be cool.
I think we can do it.
More information about the llvm-commits