1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

[MemorySSA] Invalidate def caches on deletion

The only cases I can come up with where this invalidation needs to
happen is when there's a deletion somewhere. If we find more creative
test-cases, we can probably go with another approach mentioned on
PR36529.

Fixes PR36529.

llvm-svn: 326177
This commit is contained in:
George Burgess IV 2018-02-27 07:20:49 +00:00
parent f0bdcb7452
commit e3a72f8453
2 changed files with 52 additions and 2 deletions

View File

@ -381,7 +381,9 @@ public:
OptimizedID = getDefiningAccess()->getID();
}
MemoryAccess *getOptimized() const { return Optimized; }
MemoryAccess *getOptimized() const {
return cast_or_null<MemoryAccess>(Optimized);
}
bool isOptimized() const {
return getOptimized() && getDefiningAccess() &&
@ -401,7 +403,7 @@ private:
const unsigned ID;
unsigned OptimizedID = INVALID_MEMORYACCESS_ID;
MemoryAccess *Optimized = nullptr;
WeakVH Optimized;
};
template <>

View File

@ -951,3 +951,51 @@ TEST_F(MemorySSATest, MoveToBeforeLiveOnEntryInvalidatesCache) {
MSSA.getLiveOnEntryDef())
<< "(DefA = " << DefA << ")";
}
TEST_F(MemorySSATest, RemovingDefInvalidatesCache) {
// Create:
// %x = alloca i8
// %y = alloca i8
// ; 1 = MemoryDef(liveOnEntry)
// store i8 0, i8* %x
// ; 2 = MemoryDef(1)
// store i8 0, i8* %y
// ; 3 = MemoryDef(2)
// store i8 0, i8* %x
//
// And be sure that MSSA's caching handles the removal of def `1`
// appropriately.
IRBuilder<> B(C);
F = Function::Create(
FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
GlobalValue::ExternalLinkage, "F", &M);
BasicBlock *Entry = BasicBlock::Create(C, "if", F);
B.SetInsertPoint(Entry);
Value *X = B.CreateAlloca(B.getInt8Ty());
Value *Y = B.CreateAlloca(B.getInt8Ty());
StoreInst *StoreX1 = B.CreateStore(B.getInt8(0), X);
StoreInst *StoreY = B.CreateStore(B.getInt8(0), Y);
StoreInst *StoreX2 = B.CreateStore(B.getInt8(0), X);
setupAnalyses();
MemorySSA &MSSA = *Analyses->MSSA;
auto *DefX1 = cast<MemoryDef>(MSSA.getMemoryAccess(StoreX1));
auto *DefY = cast<MemoryDef>(MSSA.getMemoryAccess(StoreY));
auto *DefX2 = cast<MemoryDef>(MSSA.getMemoryAccess(StoreX2));
EXPECT_EQ(DefX2->getDefiningAccess(), DefY);
MemoryAccess *X2Clobber = MSSA.getWalker()->getClobberingMemoryAccess(DefX2);
ASSERT_EQ(DefX1, X2Clobber);
MemorySSAUpdater(&MSSA).removeMemoryAccess(DefX1);
StoreX1->eraseFromParent();
EXPECT_EQ(DefX2->getDefiningAccess(), DefY);
EXPECT_EQ(MSSA.getWalker()->getClobberingMemoryAccess(DefX2),
MSSA.getLiveOnEntryDef())
<< "(DefX1 = " << DefX1 << ")";
}