mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-05 02:16:46 +00:00
[LoopDist] Improve variable names and comments in LoopVersioning class, NFC
As with the previous patch, the goal is to turn the class into a general loop-versioning class. This patch removes any references to loop distribution. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240352 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0c17f95006
commit
08056a49f1
@ -635,10 +635,11 @@ public:
|
||||
LoopVersioning(const LoopAccessInfo &LAI, Loop *L, LoopInfo *LI,
|
||||
DominatorTree *DT,
|
||||
const SmallVector<int, 8> *PtrToPartition = nullptr)
|
||||
: OrigLoop(L), NonDistributedLoop(nullptr),
|
||||
: VersionedLoop(L), NonVersionedLoop(nullptr),
|
||||
PtrToPartition(PtrToPartition), LAI(LAI), LI(LI), DT(DT) {}
|
||||
|
||||
/// \brief Returns true if we need memchecks to distribute the loop.
|
||||
/// \brief Returns true if we need memchecks to disambiguate may-aliasing
|
||||
/// accesses.
|
||||
bool needsRuntimeChecks() const {
|
||||
return LAI.getRuntimePointerCheck()->needsAnyChecking(PtrToPartition);
|
||||
}
|
||||
@ -649,49 +650,51 @@ public:
|
||||
Instruction *FirstCheckInst;
|
||||
Instruction *MemRuntimeCheck;
|
||||
// Add the memcheck in the original preheader (this is empty initially).
|
||||
BasicBlock *MemCheckBB = OrigLoop->getLoopPreheader();
|
||||
BasicBlock *MemCheckBB = VersionedLoop->getLoopPreheader();
|
||||
std::tie(FirstCheckInst, MemRuntimeCheck) =
|
||||
LAI.addRuntimeCheck(MemCheckBB->getTerminator(), PtrToPartition);
|
||||
assert(MemRuntimeCheck && "called even though needsAnyChecking = false");
|
||||
|
||||
// Rename the block to make the IR more readable.
|
||||
MemCheckBB->setName(OrigLoop->getHeader()->getName() + ".ldist.memcheck");
|
||||
MemCheckBB->setName(VersionedLoop->getHeader()->getName() +
|
||||
".lver.memcheck");
|
||||
|
||||
// Create empty preheader for the loop (and after cloning for the
|
||||
// original/nondist loop).
|
||||
// non-versioned loop).
|
||||
BasicBlock *PH =
|
||||
SplitBlock(MemCheckBB, MemCheckBB->getTerminator(), DT, LI);
|
||||
PH->setName(OrigLoop->getHeader()->getName() + ".ph");
|
||||
PH->setName(VersionedLoop->getHeader()->getName() + ".ph");
|
||||
|
||||
// Clone the loop including the preheader.
|
||||
//
|
||||
// FIXME: This does not currently preserve SimplifyLoop because the exit
|
||||
// block is a join between the two loops.
|
||||
SmallVector<BasicBlock *, 8> NonDistributedLoopBlocks;
|
||||
NonDistributedLoop =
|
||||
cloneLoopWithPreheader(PH, MemCheckBB, OrigLoop, VMap, ".ldist.nondist",
|
||||
LI, DT, NonDistributedLoopBlocks);
|
||||
remapInstructionsInLoop(NonDistributedLoopBlocks, VMap);
|
||||
SmallVector<BasicBlock *, 8> NonVersionedLoopBlocks;
|
||||
NonVersionedLoop =
|
||||
cloneLoopWithPreheader(PH, MemCheckBB, VersionedLoop, VMap,
|
||||
".lver.orig", LI, DT, NonVersionedLoopBlocks);
|
||||
remapInstructionsInLoop(NonVersionedLoopBlocks, VMap);
|
||||
|
||||
// Insert the conditional branch based on the result of the memchecks.
|
||||
Instruction *OrigTerm = MemCheckBB->getTerminator();
|
||||
BranchInst::Create(NonDistributedLoop->getLoopPreheader(),
|
||||
OrigLoop->getLoopPreheader(), MemRuntimeCheck, OrigTerm);
|
||||
BranchInst::Create(NonVersionedLoop->getLoopPreheader(),
|
||||
VersionedLoop->getLoopPreheader(), MemRuntimeCheck,
|
||||
OrigTerm);
|
||||
OrigTerm->eraseFromParent();
|
||||
|
||||
// The loops merge in the original exit block. This is now dominated by the
|
||||
// memchecking block.
|
||||
DT->changeImmediateDominator(OrigLoop->getExitBlock(), MemCheckBB);
|
||||
DT->changeImmediateDominator(VersionedLoop->getExitBlock(), MemCheckBB);
|
||||
}
|
||||
|
||||
/// \brief Adds the necessary PHI nodes for the versioned loops based on the
|
||||
/// loop-defined values used outside of the loop.
|
||||
void addPHINodes(const SmallVectorImpl<Instruction *> &DefsUsedOutside) {
|
||||
BasicBlock *PHIBlock = OrigLoop->getExitBlock();
|
||||
BasicBlock *PHIBlock = VersionedLoop->getExitBlock();
|
||||
assert(PHIBlock && "No single successor to loop exit block");
|
||||
|
||||
for (auto *Inst : DefsUsedOutside) {
|
||||
auto *NonDistInst = cast<Instruction>(VMap[Inst]);
|
||||
auto *NonVersionedLoopInst = cast<Instruction>(VMap[Inst]);
|
||||
PHINode *PN;
|
||||
|
||||
// First see if we have a single-operand PHI with the value defined by the
|
||||
@ -704,24 +707,25 @@ public:
|
||||
}
|
||||
// If not create it.
|
||||
if (!PN) {
|
||||
PN = PHINode::Create(Inst->getType(), 2, Inst->getName() + ".ldist",
|
||||
PN = PHINode::Create(Inst->getType(), 2, Inst->getName() + ".lver",
|
||||
PHIBlock->begin());
|
||||
for (auto *User : Inst->users())
|
||||
if (!OrigLoop->contains(cast<Instruction>(User)->getParent()))
|
||||
if (!VersionedLoop->contains(cast<Instruction>(User)->getParent()))
|
||||
User->replaceUsesOfWith(Inst, PN);
|
||||
PN->addIncoming(Inst, OrigLoop->getExitingBlock());
|
||||
PN->addIncoming(Inst, VersionedLoop->getExitingBlock());
|
||||
}
|
||||
// Add the new incoming value from the non-distributed loop.
|
||||
PN->addIncoming(NonDistInst, NonDistributedLoop->getExitingBlock());
|
||||
// Add the new incoming value from the non-versioned loop.
|
||||
PN->addIncoming(NonVersionedLoopInst,
|
||||
NonVersionedLoop->getExitingBlock());
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
/// \brief The original loop. This becomes the "versioned" one, i.e. control
|
||||
/// goes if the memchecks all pass.
|
||||
Loop *OrigLoop;
|
||||
Loop *VersionedLoop;
|
||||
/// \brief The fall-back loop, i.e. if any of the memchecks fail.
|
||||
Loop *NonDistributedLoop;
|
||||
Loop *NonVersionedLoop;
|
||||
|
||||
/// \brief For each memory pointer it contains the partitionId it is used in.
|
||||
/// If nullptr, no partitioning is used.
|
||||
@ -730,8 +734,8 @@ private:
|
||||
/// If the pointer is used in multiple partitions the entry is set to -1.
|
||||
const SmallVector<int, 8> *PtrToPartition;
|
||||
|
||||
/// \brief This maps the instructions from OrigLoop to their counterpart in
|
||||
/// NonDistributedLoop.
|
||||
/// \brief This maps the instructions from VersionedLoop to their counterpart
|
||||
/// in NonVersionedLoop.
|
||||
ValueToValueMapTy VMap;
|
||||
|
||||
/// \brief Analyses used.
|
||||
|
@ -35,7 +35,7 @@ entry:
|
||||
; We have two compares for each array overlap check which is a total of 10
|
||||
; compares.
|
||||
;
|
||||
; CHECK: for.body.ldist.memcheck:
|
||||
; CHECK: for.body.lver.memcheck:
|
||||
; CHECK: = icmp
|
||||
; CHECK: = icmp
|
||||
|
||||
@ -52,14 +52,14 @@ entry:
|
||||
; CHECK: = icmp
|
||||
|
||||
; CHECK-NOT: = icmp
|
||||
; CHECK: br i1 %memcheck.conflict, label %for.body.ph.ldist.nondist, label %for.body.ph.ldist1
|
||||
; CHECK: br i1 %memcheck.conflict, label %for.body.ph.lver.orig, label %for.body.ph.ldist1
|
||||
|
||||
; The non-distributed loop that the memchecks fall back on.
|
||||
|
||||
; CHECK: for.body.ph.ldist.nondist:
|
||||
; CHECK: br label %for.body.ldist.nondist
|
||||
; CHECK: for.body.ldist.nondist:
|
||||
; CHECK: br i1 %exitcond.ldist.nondist, label %for.end, label %for.body.ldist.nondist
|
||||
; CHECK: for.body.ph.lver.orig:
|
||||
; CHECK: br label %for.body.lver.orig
|
||||
; CHECK: for.body.lver.orig:
|
||||
; CHECK: br i1 %exitcond.lver.orig, label %for.end, label %for.body.lver.orig
|
||||
|
||||
; Verify the two distributed loops.
|
||||
|
||||
|
@ -37,7 +37,7 @@ entry:
|
||||
; CHECK: for.body:
|
||||
; CHECK: %sum_add = add nuw nsw i32 %sum, %loadC
|
||||
; CHECK: for.end:
|
||||
; CHECK: %sum_add.ldist = phi i32 [ %sum_add, %for.body ], [ %sum_add.ldist.nondist, %for.body.ldist.nondist ]
|
||||
; CHECK: %sum_add.lver = phi i32 [ %sum_add, %for.body ], [ %sum_add.lver.orig, %for.body.lver.orig ]
|
||||
|
||||
for.body: ; preds = %for.body, %entry
|
||||
%ind = phi i64 [ 0, %entry ], [ %add, %for.body ]
|
||||
|
Loading…
Reference in New Issue
Block a user