When splitting predecessors in BasicBlockUtils, we create a new block as an immediate predecessor of the original BB, then we connect a given set of predecessors to the new block.
The API in this patch will be used to update MemoryPhis for this CFG change.
If all predecessors are being moved, we move the MemoryPhi directly. Otherwise we create a new MemoryPhi in the NewBB and populate its incoming values, while deleting them from BB's Phi.
[Split from D45299 for easier review]
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
Consider multiple edges between blocks. MemoryPhis have an entry for each edge in this case. Move all edges to the new phi to preserve number of edges equal to number of phi entries.
lib/Analysis/MemorySSAUpdater.cpp | ||
---|---|---|
499 ↗ | (On Diff #154899) | nit: Please just use ! instead of == nullptr, for consistency |
504 ↗ | (On Diff #154899) | Doesn't pred_size(Old) == 1 imply that pred_size(New) == Preds.size() must be true? Or is there a case I'm missing? |
507 ↗ | (On Diff #154899) | nit: s/Preds.size() > 0/!Preds.empty()/ |
517 ↗ | (On Diff #154899) | Looks like we could do this in O(Preds.size() + Phi->getNumOperands()) time if we instead used a SmallPtrSet for Preds and did a single walk over the operands list, querying the SmallPtrSet for whether $current_operand is something we could remove. If we made a general utility for Phis similar in spirit to llvm::erase_if for this, looks like we could even make unorderedDeleteIncomingBlock and unorderedDeleteIncomingValue tiny wrappers around that. It would arguably be mildly awkward to have the addIncoming side-effect from the lambda there, but I'd imagine it would be cleaner on the whole. WDYT? |
lib/Analysis/MemorySSAUpdater.cpp | ||
---|---|---|
517 ↗ | (On Diff #154899) | I think I like this more than the alternatives I thought about. So here goes :) |
include/llvm/Analysis/MemorySSA.h | ||
---|---|---|
581 ↗ | (On Diff #155273) | s/entried/entries |
lib/Analysis/MemorySSAUpdater.cpp | ||
516 ↗ | (On Diff #155273) | Can we replace Phi->getIncomingValueForBlock(B) with the MemoryAccess * we're passed in (if we make it non-const)? |
517 ↗ | (On Diff #154899) | Did making a SmallPtrSet of Preds not work? |
llvm/trunk/include/llvm/Analysis/MemorySSAUpdater.h | ||
---|---|---|
133 | I was trying to understand this comment in the context of https://reviews.llvm.org/D45300 and I think it can be improved slightly. Instead of saying "before" and "point to" we should use more specific "branches to" terminology. I.e. something like: Old now has New, an empty BasicBlock, branching directly to it, and the predecessors in Preds that used to branch to Old, now branch to New. If New is the only predecessor, move Old's Phi, if present, to New. Otherwise, add a new Phi in New with appropriate incoming values, and update the incoming values in Old's Phi node too, if present. |
llvm/trunk/include/llvm/Analysis/MemorySSAUpdater.h | ||
---|---|---|
133 | Thanks! Updated in r340192. |
I was trying to understand this comment in the context of https://reviews.llvm.org/D45300 and I think it can be improved slightly. Instead of saying "before" and "point to" we should use more specific "branches to" terminology. I.e. something like: