summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorAlina Sbirlea <asbirlea@google.com>2018-07-11 22:11:46 +0000
committerAlina Sbirlea <asbirlea@google.com>2018-07-11 22:11:46 +0000
commit0f53355e83a7b20a892850aef0266a41a9f1c446 (patch)
treea163c51882fecd723125ec3a310dbe34b1b3e62e /llvm
parenta09b9317f5a1dcd29efd1253c6ee29faefd477fe (diff)
downloadbcm5719-llvm-0f53355e83a7b20a892850aef0266a41a9f1c446.tar.gz
bcm5719-llvm-0f53355e83a7b20a892850aef0266a41a9f1c446.zip
[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 llvm-svn: 336860
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/Analysis/MemorySSA.h2
-rw-r--r--llvm/include/llvm/Analysis/MemorySSAUpdater.h34
-rw-r--r--llvm/lib/Analysis/MemorySSA.cpp12
-rw-r--r--llvm/lib/Analysis/MemorySSAUpdater.cpp50
4 files changed, 96 insertions, 2 deletions
diff --git a/llvm/include/llvm/Analysis/MemorySSA.h b/llvm/include/llvm/Analysis/MemorySSA.h
index a8749ee769c..342aefcaa7e 100644
--- a/llvm/include/llvm/Analysis/MemorySSA.h
+++ b/llvm/include/llvm/Analysis/MemorySSA.h
@@ -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,
diff --git a/llvm/include/llvm/Analysis/MemorySSAUpdater.h b/llvm/include/llvm/Analysis/MemorySSAUpdater.h
index 6a07623a047..cf6a2e4a315 100644
--- a/llvm/include/llvm/Analysis/MemorySSAUpdater.h
+++ b/llvm/include/llvm/Analysis/MemorySSAUpdater.h
@@ -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 *
diff --git a/llvm/lib/Analysis/MemorySSA.cpp b/llvm/lib/Analysis/MemorySSA.cpp
index fe89c1d9570..f57d490ce96 100644
--- a/llvm/lib/Analysis/MemorySSA.cpp
+++ b/llvm/lib/Analysis/MemorySSA.cpp
@@ -1473,8 +1473,18 @@ void MemorySSA::moveTo(MemoryUseOrDef *What, BasicBlock *BB,
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);
diff --git a/llvm/lib/Analysis/MemorySSAUpdater.cpp b/llvm/lib/Analysis/MemorySSAUpdater.cpp
index d2e4bfe51ec..54184775e97 100644
--- a/llvm/lib/Analysis/MemorySSAUpdater.cpp
+++ b/llvm/lib/Analysis/MemorySSAUpdater.cpp
@@ -430,6 +430,56 @@ void MemorySSAUpdater::moveToPlace(MemoryUseOrDef *What, BasicBlock *BB,
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) {
OpenPOWER on IntegriCloud