MemoryPhis now have APIs analogous to BB Phis to remove an incoming value/block.
The MemorySSAUpdater uses the above APIs when updating MemorySSA given a set of dead blocks about to be deleted.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
Thanks for this!
include/llvm/Analysis/MemorySSA.h | ||
---|---|---|
566 ↗ | (On Diff #152179) | nit: I don't think we encourage const on value params |
566 ↗ | (On Diff #152179) | Naming nit: do you think it would be good to call out that these methods don't preserve the Phi's operand ordering? If so, please add either an unordered prefix/suffix to these. (I've no issue with the swap-and-pop_back idiom; I just want it to be obvious at each callsite that the order might be changed) |
568 ↗ | (On Diff #152179) | Nit: The parens around (I < E) are unnecessary (and on line 569 + 585 + 597) |
570 ↗ | (On Diff #152179) | Please add a comment explaining why (I'm assuming it's something like "otherwise, we should just be deleting the Phi outright") |
lib/Analysis/MemorySSAUpdater.cpp | ||
501 ↗ | (On Diff #152179) | nit: if (TerminatorInst *TI = BB->getTerminator()). Do we expect to see broken IR here, though? It's my impression that BBs should always have a terminator when they're in a complete-enough state. If yes, please add a comment explaining how broken we expect our IR to be when this method is called. :) |
514 ↗ | (On Diff #152179) | Do we need to look this up on every iteration? |
519 ↗ | (On Diff #152179) | This is already done in Value::~Value(), which should be called by MemorySSA::removeFromLists. Does it need to be repeated here? (Especially given that we skip this extra check for Uses.) |
524 ↗ | (On Diff #152179) | cast<MemoryAccess> |
531 ↗ | (On Diff #152179) | Can we set this to nullptr instead, like Value::dropAllReferences does? (I also think this could be simplified a fair amount if we swapped to dropAllReferences in the loop above + a deletion pass after that, but if that's inferior to this somehow, I'm happy to accept this approach. Value's dtor should cover the "User must be deleted too." assert for us) |
538 ↗ | (On Diff #152179) | In the interest of getting rid of soon-to-be-dangling pointers, we should probably remove all of DeadBlocks from MemorySSA::BlockNumberingValid, too. I think that would fit best in MemorySSA::removeFromLists, though |
lib/Analysis/MemorySSAUpdater.cpp | ||
---|---|---|
501 ↗ | (On Diff #152179) | TI should be null for empty blocks. I don't have a use case, but it seemed a reasonable safety check. I can remove it if you think it's unnecessary. |
531 ↗ | (On Diff #152179) | Added dropAllReferences above, only updating lists here. |
538 ↗ | (On Diff #152179) | Added in MemorySSA::removeFromLookups where BlockNumbering is also updated. |
include/llvm/Analysis/MemorySSAUpdater.h | ||
---|---|---|
153 ↗ | (On Diff #152551) | Did you mean "predecessor edges"? |
lib/Analysis/MemorySSA.cpp | ||
1576 ↗ | (On Diff #152551) | The numbering is still valid even if we remove MA, though :) We don't really care if the numbering has gaps. We only care that the block numbers increase as you iterate through an AccessList. |
lib/Analysis/MemorySSAUpdater.cpp | ||
501 ↗ | (On Diff #152179) | Personally, I have a slight preference for asserting that the IR is well-formed until we know that we can't, but if you'd prefer to have a check here, I'm OK with that. |
LGTM with one remaining nit. Thanks again!
lib/Analysis/MemorySSA.cpp | ||
---|---|---|
1623 ↗ | (On Diff #152962) | Nit: can we put this in the if (Accesses->empty()) block? I think the purpose is just to guard us from dangling pointers, and the only time we should (reasonably) carry a dangling pointer here is if we're removing the last access from this block. |