[llvm] r336860 - [MemorySSA] Add APIs to move memory accesses between blocks, following CFG changes.
Alina Sbirlea via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 11 15:11:46 PDT 2018
Author: asbirlea
Date: Wed Jul 11 15:11:46 2018
New Revision: 336860
URL: http://llvm.org/viewvc/llvm-project?rev=336860&view=rev
Log:
[MemorySSA] Add APIs to move memory accesses between blocks, following CFG changes.
Summary:
The move APIs added in this patch will be used to update MemorySSA when CFG changes merge or split blocks, by moving memory accesses accordingly in MemorySSA's internal data structures.
[Split from D45299 for easier review]
Reviewers: george.burgess.iv
Subscribers: sanjoy, jlebar, Prazek, llvm-commits
Differential Revision: https://reviews.llvm.org/D48897
Modified:
llvm/trunk/include/llvm/Analysis/MemorySSA.h
llvm/trunk/include/llvm/Analysis/MemorySSAUpdater.h
llvm/trunk/lib/Analysis/MemorySSA.cpp
llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp
Modified: llvm/trunk/include/llvm/Analysis/MemorySSA.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemorySSA.h?rev=336860&r1=336859&r2=336860&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/MemorySSA.h (original)
+++ llvm/trunk/include/llvm/Analysis/MemorySSA.h Wed Jul 11 15:11:46 2018
@@ -781,7 +781,7 @@ protected:
// relies on the updater to fixup what it breaks, so it is not public.
void moveTo(MemoryUseOrDef *What, BasicBlock *BB, AccessList::iterator Where);
- void moveTo(MemoryUseOrDef *What, BasicBlock *BB, InsertionPlace Point);
+ void moveTo(MemoryAccess *What, BasicBlock *BB, InsertionPlace Point);
// Rename the dominator tree branch rooted at BB.
void renamePass(BasicBlock *BB, MemoryAccess *IncomingVal,
Modified: llvm/trunk/include/llvm/Analysis/MemorySSAUpdater.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemorySSAUpdater.h?rev=336860&r1=336859&r2=336860&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/MemorySSAUpdater.h (original)
+++ llvm/trunk/include/llvm/Analysis/MemorySSAUpdater.h Wed Jul 11 15:11:46 2018
@@ -89,6 +89,37 @@ public:
void moveAfter(MemoryUseOrDef *What, MemoryUseOrDef *Where);
void moveToPlace(MemoryUseOrDef *What, BasicBlock *BB,
MemorySSA::InsertionPlace Where);
+ /// `From` block was spliced into `From` and `To`.
+ /// Move all accesses from `From` to `To` starting at instruction `Start`.
+ /// `To` is newly created BB, so empty of MemorySSA::MemoryAccesses.
+ /// Edges are already updated, so successors of `To` with MPhi nodes need to
+ /// update incoming block.
+ /// |------| |------|
+ /// | From | | From |
+ /// | | |------|
+ /// | | ||
+ /// | | => \/
+ /// | | |------| <- Start
+ /// | | | To |
+ /// |------| |------|
+ void moveAllAfterSpliceBlocks(BasicBlock *From, BasicBlock *To,
+ Instruction *Start);
+ /// `From` block was merged into `To`. All instructions were moved and
+ /// `From` is an empty block with successor edges; `From` is about to be
+ /// deleted. Move all accesses from `From` to `To` starting at instruction
+ /// `Start`. `To` may have multiple successors, `From` has a single
+ /// predecessor. `From` may have successors with MPhi nodes, replace their
+ /// incoming block with `To`.
+ /// |------| |------|
+ /// | To | | To |
+ /// |------| | |
+ /// || => | |
+ /// \/ | |
+ /// |------| | | <- Start
+ /// | From | | |
+ /// |------| |------|
+ void moveAllAfterMergeBlocks(BasicBlock *From, BasicBlock *To,
+ Instruction *Start);
// The below are utility functions. Other than creation of accesses to pass
// to insertDef, and removeAccess to remove accesses, you should generally
@@ -162,6 +193,9 @@ private:
// Move What before Where in the MemorySSA IR.
template <class WhereType>
void moveTo(MemoryUseOrDef *What, BasicBlock *BB, WhereType Where);
+ // Move all memory accesses from `From` to `To` starting at `Start`.
+ // Restrictions apply, see public wrappers of this method.
+ void moveAllAccesses(BasicBlock *From, BasicBlock *To, Instruction *Start);
MemoryAccess *getPreviousDef(MemoryAccess *);
MemoryAccess *getPreviousDefInBlock(MemoryAccess *);
MemoryAccess *
Modified: llvm/trunk/lib/Analysis/MemorySSA.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemorySSA.cpp?rev=336860&r1=336859&r2=336860&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/MemorySSA.cpp (original)
+++ llvm/trunk/lib/Analysis/MemorySSA.cpp Wed Jul 11 15:11:46 2018
@@ -1473,8 +1473,18 @@ void MemorySSA::moveTo(MemoryUseOrDef *W
insertIntoListsBefore(What, BB, Where);
}
-void MemorySSA::moveTo(MemoryUseOrDef *What, BasicBlock *BB,
+void MemorySSA::moveTo(MemoryAccess *What, BasicBlock *BB,
InsertionPlace Point) {
+ if (isa<MemoryPhi>(What)) {
+ assert(Point == Beginning &&
+ "Can only move a Phi at the beginning of the block");
+ // Update lookup table entry
+ ValueToMemoryAccess.erase(What->getBlock());
+ bool Inserted = ValueToMemoryAccess.insert({BB, What}).second;
+ (void)Inserted;
+ assert(Inserted && "Cannot move a Phi to a block that already has one");
+ }
+
removeFromLists(What, false);
What->setBlock(BB);
insertIntoListsForBlock(What, BB, Point);
Modified: llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp?rev=336860&r1=336859&r2=336860&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp (original)
+++ llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp Wed Jul 11 15:11:46 2018
@@ -430,6 +430,56 @@ void MemorySSAUpdater::moveToPlace(Memor
return moveTo(What, BB, Where);
}
+// All accesses in To used to be in From. Move to end and update access lists.
+void MemorySSAUpdater::moveAllAccesses(BasicBlock *From, BasicBlock *To,
+ Instruction *Start) {
+
+ MemorySSA::AccessList *Accs = MSSA->getWritableBlockAccesses(From);
+ if (!Accs)
+ return;
+
+ MemoryAccess *FirstInNew = nullptr;
+ for (Instruction &I : make_range(Start->getIterator(), To->end()))
+ if ((FirstInNew = MSSA->getMemoryAccess(&I)))
+ break;
+ if (!FirstInNew)
+ return;
+
+ auto *MUD = cast<MemoryUseOrDef>(FirstInNew);
+ do {
+ auto NextIt = ++MUD->getIterator();
+ MemoryUseOrDef *NextMUD = (!Accs || NextIt == Accs->end())
+ ? nullptr
+ : cast<MemoryUseOrDef>(&*NextIt);
+ MSSA->moveTo(MUD, To, MemorySSA::End);
+ // Moving MUD from Accs in the moveTo above, may delete Accs, so we need to
+ // retrieve it again.
+ Accs = MSSA->getWritableBlockAccesses(From);
+ MUD = NextMUD;
+ } while (MUD);
+}
+
+void MemorySSAUpdater::moveAllAfterSpliceBlocks(BasicBlock *From,
+ BasicBlock *To,
+ Instruction *Start) {
+ assert(MSSA->getBlockAccesses(To) == nullptr &&
+ "To block is expected to be free of MemoryAccesses.");
+ moveAllAccesses(From, To, Start);
+ for (BasicBlock *Succ : successors(To))
+ if (MemoryPhi *MPhi = MSSA->getMemoryAccess(Succ))
+ MPhi->setIncomingBlock(MPhi->getBasicBlockIndex(From), To);
+}
+
+void MemorySSAUpdater::moveAllAfterMergeBlocks(BasicBlock *From, BasicBlock *To,
+ Instruction *Start) {
+ assert(From->getSinglePredecessor() == To &&
+ "From block is expected to have a single predecessor (To).");
+ moveAllAccesses(From, To, Start);
+ for (BasicBlock *Succ : successors(From))
+ if (MemoryPhi *MPhi = MSSA->getMemoryAccess(Succ))
+ MPhi->setIncomingBlock(MPhi->getBasicBlockIndex(From), To);
+}
+
/// If all arguments of a MemoryPHI are defined by the same incoming
/// argument, return that argument.
static MemoryAccess *onlySingleValue(MemoryPhi *MP) {
More information about the llvm-commits
mailing list