1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[MemorySSA] Extend allowed behavior for simplified instructions.

Summary:
LoopRotate may simplify instructions, leading to the new instructions not having memory accesses created for them.
Allow this behavior, by allowing the new access to be null when the template is null, and looking upwards for the proper defined access when dealing with simplified instructions.

Reviewers: george.burgess.iv

Subscribers: jlebar, Prazek, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D65338

llvm-svn: 367352
This commit is contained in:
Alina Sbirlea 2019-07-30 20:10:33 +00:00
parent 231a6534b0
commit 3ef8f1e34d
4 changed files with 82 additions and 28 deletions

View File

@ -830,7 +830,8 @@ protected:
void insertIntoListsBefore(MemoryAccess *, const BasicBlock *,
AccessList::iterator);
MemoryUseOrDef *createDefinedAccess(Instruction *, MemoryAccess *,
const MemoryUseOrDef *Template = nullptr);
const MemoryUseOrDef *Template = nullptr,
bool CreationMustSucceed = true);
private:
template <class AliasAnalysisType> class ClobberWalkerBase;

View File

@ -1687,12 +1687,14 @@ MemoryPhi *MemorySSA::createMemoryPhi(BasicBlock *BB) {
MemoryUseOrDef *MemorySSA::createDefinedAccess(Instruction *I,
MemoryAccess *Definition,
const MemoryUseOrDef *Template) {
const MemoryUseOrDef *Template,
bool CreationMustSucceed) {
assert(!isa<PHINode>(I) && "Cannot create a defined access for a PHI");
MemoryUseOrDef *NewAccess = createNewAccess(I, AA, Template);
assert(
NewAccess != nullptr &&
"Tried to create a memory access for a non-memory touching instruction");
if (CreationMustSucceed)
assert(NewAccess != nullptr && "Tried to create a memory access for a "
"non-memory touching instruction");
if (NewAccess)
NewAccess->setDefiningAccess(Definition);
return NewAccess;
}

View File

@ -480,19 +480,33 @@ void MemorySSAUpdater::removeDuplicatePhiEdgesBetween(const BasicBlock *From,
}
}
void MemorySSAUpdater::cloneUsesAndDefs(BasicBlock *BB, BasicBlock *NewBB,
static MemoryAccess *getNewDefiningAccessForClone(MemoryAccess *MA,
const ValueToValueMapTy &VMap,
PhiToDefMap &MPhiMap,
bool CloneWasSimplified) {
auto GetNewDefiningAccess = [&](MemoryAccess *MA) -> MemoryAccess * {
bool CloneWasSimplified,
MemorySSA *MSSA) {
MemoryAccess *InsnDefining = MA;
if (MemoryUseOrDef *DefMUD = dyn_cast<MemoryUseOrDef>(InsnDefining)) {
if (MemoryDef *DefMUD = dyn_cast<MemoryDef>(InsnDefining)) {
if (!MSSA->isLiveOnEntryDef(DefMUD)) {
Instruction *DefMUDI = DefMUD->getMemoryInst();
assert(DefMUDI && "Found MemoryUseOrDef with no Instruction.");
if (Instruction *NewDefMUDI =
cast_or_null<Instruction>(VMap.lookup(DefMUDI)))
cast_or_null<Instruction>(VMap.lookup(DefMUDI))) {
InsnDefining = MSSA->getMemoryAccess(NewDefMUDI);
if (!CloneWasSimplified)
assert(InsnDefining && "Defining instruction cannot be nullptr.");
else if (!InsnDefining || isa<MemoryUse>(InsnDefining)) {
// The clone was simplified, it's no longer a MemoryDef, look up.
auto DefIt = DefMUD->getDefsIterator();
// Since simplified clones only occur in single block cloning, a
// previous definition must exist, otherwise NewDefMUDI would not
// have been found in VMap.
assert(DefIt != MSSA->getBlockDefs(DefMUD->getBlock())->begin() &&
"Previous def must exist");
InsnDefining = getNewDefiningAccessForClone(
&*(--DefIt), VMap, MPhiMap, CloneWasSimplified, MSSA);
}
}
}
} else {
MemoryPhi *DefPhi = cast<MemoryPhi>(InsnDefining);
@ -501,8 +515,12 @@ void MemorySSAUpdater::cloneUsesAndDefs(BasicBlock *BB, BasicBlock *NewBB,
}
assert(InsnDefining && "Defining instruction cannot be nullptr.");
return InsnDefining;
};
}
void MemorySSAUpdater::cloneUsesAndDefs(BasicBlock *BB, BasicBlock *NewBB,
const ValueToValueMapTy &VMap,
PhiToDefMap &MPhiMap,
bool CloneWasSimplified) {
const MemorySSA::AccessList *Acc = MSSA->getBlockAccesses(BB);
if (!Acc)
return;
@ -519,8 +537,12 @@ void MemorySSAUpdater::cloneUsesAndDefs(BasicBlock *BB, BasicBlock *NewBB,
if (Instruction *NewInsn =
dyn_cast_or_null<Instruction>(VMap.lookup(Insn))) {
MemoryAccess *NewUseOrDef = MSSA->createDefinedAccess(
NewInsn, GetNewDefiningAccess(MUD->getDefiningAccess()),
CloneWasSimplified ? nullptr : MUD);
NewInsn,
getNewDefiningAccessForClone(MUD->getDefiningAccess(), VMap,
MPhiMap, CloneWasSimplified, MSSA),
/*Template=*/CloneWasSimplified ? nullptr : MUD,
/*CreationMustSucceed=*/CloneWasSimplified ? false : true);
if (NewUseOrDef)
MSSA->insertIntoListsForBlock(NewUseOrDef, NewBB, MemorySSA::End);
}
}

View File

@ -0,0 +1,29 @@
; RUN: opt -verify-memoryssa -enable-mssa-loop-dependency -loop-rotate %s -S | FileCheck %s
; REQUIRES: asserts
; CHECK-LABEL: @test()
define dso_local void @test() {
entry:
br label %preheader
preheader:
br label %l39
l39:
%v40 = phi float (float)* [ @foo, %preheader ], [ %v43, %crit_edge ]
%v41 = call float %v40(float undef)
%v42 = load i32, i32* undef, align 8
br i1 undef, label %crit_edge, label %loopexit
crit_edge:
%v43 = load float (float)*, float (float)** undef, align 8
br label %l39
loopexit:
unreachable
}
; Function Attrs: readnone
declare dso_local float @foo(float) #0 align 32
attributes #0 = { readnone }