[llvm] r290527 - [MemorySSA] Define a restricted upward AccessList splice.
Bryant Wong via llvm-commits
llvm-commits at lists.llvm.org
Sun Dec 25 15:34:07 PST 2016
Author: bryant
Date: Sun Dec 25 17:34:07 2016
New Revision: 290527
URL: http://llvm.org/viewvc/llvm-project?rev=290527&view=rev
Log:
[MemorySSA] Define a restricted upward AccessList splice.
Differential Revision: https://reviews.llvm.org/D26661
Modified:
llvm/trunk/include/llvm/Transforms/Utils/MemorySSA.h
llvm/trunk/lib/Transforms/Utils/MemorySSA.cpp
llvm/trunk/unittests/Transforms/Utils/MemorySSA.cpp
Modified: llvm/trunk/include/llvm/Transforms/Utils/MemorySSA.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/MemorySSA.h?rev=290527&r1=290526&r2=290527&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/MemorySSA.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/MemorySSA.h Sun Dec 25 17:34:07 2016
@@ -578,6 +578,15 @@ public:
MemoryAccess *Definition,
MemoryAccess *InsertPt);
+ // \brief Splice \p What to just before \p Where.
+ //
+ // In order to be efficient, the following conditions must be met:
+ // - \p Where dominates \p What,
+ // - All memory accesses in [\p Where, \p What) are no-alias with \p What.
+ //
+ // TODO: relax the MemoryDef requirement on Where.
+ void spliceMemoryAccessAbove(MemoryDef *Where, MemoryUseOrDef *What);
+
/// \brief Remove a MemoryAccess from MemorySSA, including updating all
/// definitions and uses.
/// This should be called when a memory instruction that has a MemoryAccess
Modified: llvm/trunk/lib/Transforms/Utils/MemorySSA.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/MemorySSA.cpp?rev=290527&r1=290526&r2=290527&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/MemorySSA.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/MemorySSA.cpp Sun Dec 25 17:34:07 2016
@@ -1623,6 +1623,29 @@ MemoryUseOrDef *MemorySSA::createMemoryA
return NewAccess;
}
+void MemorySSA::spliceMemoryAccessAbove(MemoryDef *Where,
+ MemoryUseOrDef *What) {
+ assert(What != getLiveOnEntryDef() &&
+ Where != getLiveOnEntryDef() && "Can't splice (above) LOE.");
+ assert(dominates(Where, What) && "Only upwards splices are permitted.");
+
+ if (Where == What)
+ return;
+ if (isa<MemoryDef>(What)) {
+ // TODO: possibly use removeMemoryAccess' more efficient RAUW
+ What->replaceAllUsesWith(What->getDefiningAccess());
+ What->setDefiningAccess(Where->getDefiningAccess());
+ Where->setDefiningAccess(What);
+ }
+ AccessList *Src = getWritableBlockAccesses(What->getBlock());
+ AccessList *Dest = getWritableBlockAccesses(Where->getBlock());
+ Dest->splice(AccessList::iterator(Where), *Src, What);
+
+ BlockNumberingValid.erase(What->getBlock());
+ if (What->getBlock() != Where->getBlock())
+ BlockNumberingValid.erase(Where->getBlock());
+}
+
/// \brief Helper function to create new memory accesses
MemoryUseOrDef *MemorySSA::createNewAccess(Instruction *I) {
// The assume intrinsic has a control dependency which we model by claiming
Modified: llvm/trunk/unittests/Transforms/Utils/MemorySSA.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Transforms/Utils/MemorySSA.cpp?rev=290527&r1=290526&r2=290527&view=diff
==============================================================================
--- llvm/trunk/unittests/Transforms/Utils/MemorySSA.cpp (original)
+++ llvm/trunk/unittests/Transforms/Utils/MemorySSA.cpp Sun Dec 25 17:34:07 2016
@@ -484,3 +484,51 @@ TEST_F(MemorySSATest, WalkerReopt) {
EXPECT_EQ(Walker->getClobberingMemoryAccess(NewLoadAccess), LoadClobber);
EXPECT_EQ(NewLoadAccess->getDefiningAccess(), LoadClobber);
}
+
+// Test out MemorySSA::spliceMemoryAccessAbove.
+TEST_F(MemorySSATest, SpliceAboveMemoryDef) {
+ F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false),
+ GlobalValue::ExternalLinkage, "F", &M);
+ B.SetInsertPoint(BasicBlock::Create(C, "", F));
+
+ Type *Int8 = Type::getInt8Ty(C);
+ Value *A = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
+ Value *B_ = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "B");
+ Value *C = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "C");
+
+ StoreInst *StoreA0 = B.CreateStore(ConstantInt::get(Int8, 0), A);
+ StoreInst *StoreB = B.CreateStore(ConstantInt::get(Int8, 0), B_);
+ LoadInst *LoadB = B.CreateLoad(B_);
+ StoreInst *StoreA1 = B.CreateStore(ConstantInt::get(Int8, 4), A);
+ // splice this above StoreB
+ StoreInst *StoreC = B.CreateStore(ConstantInt::get(Int8, 4), C);
+ StoreInst *StoreA2 = B.CreateStore(ConstantInt::get(Int8, 4), A);
+ LoadInst *LoadC = B.CreateLoad(C);
+
+ setupAnalyses();
+ MemorySSA &MSSA = *Analyses->MSSA;
+ MemorySSAWalker &Walker = *Analyses->Walker;
+
+ StoreC->moveBefore(StoreB);
+ MSSA.spliceMemoryAccessAbove(cast<MemoryDef>(MSSA.getMemoryAccess(StoreB)),
+ MSSA.getMemoryAccess(StoreC));
+
+ MSSA.verifyMemorySSA();
+
+ EXPECT_EQ(MSSA.getMemoryAccess(StoreB)->getDefiningAccess(),
+ MSSA.getMemoryAccess(StoreC));
+ EXPECT_EQ(MSSA.getMemoryAccess(StoreC)->getDefiningAccess(),
+ MSSA.getMemoryAccess(StoreA0));
+ EXPECT_EQ(MSSA.getMemoryAccess(StoreA2)->getDefiningAccess(),
+ MSSA.getMemoryAccess(StoreA1));
+ EXPECT_EQ(Walker.getClobberingMemoryAccess(LoadB),
+ MSSA.getMemoryAccess(StoreB));
+ EXPECT_EQ(Walker.getClobberingMemoryAccess(LoadC),
+ MSSA.getMemoryAccess(StoreC));
+
+ // exercise block numbering
+ EXPECT_TRUE(MSSA.locallyDominates(MSSA.getMemoryAccess(StoreC),
+ MSSA.getMemoryAccess(StoreB)));
+ EXPECT_TRUE(MSSA.locallyDominates(MSSA.getMemoryAccess(StoreA1),
+ MSSA.getMemoryAccess(StoreA2)));
+}
More information about the llvm-commits
mailing list