summaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
commit344a3780b2e33f6ca763666c380202b18aab72a3 (patch)
treef0b203ee6eb71d7fdd792373e3c81eb18d6934dd /llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp
parentb60736ec1405bb0a8dd40989f67ef4c93da068ab (diff)
Diffstat (limited to 'llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp33
1 files changed, 27 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp b/llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp
index 6e32a2b865aa..6efaa012aeca 100644
--- a/llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp
+++ b/llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp
@@ -141,6 +141,7 @@ template <typename T>
static bool processHeaderPhiOperands(BasicBlock *Header, BasicBlock *Latch,
BasicBlockSet &AftBlocks, T Visit) {
SmallVector<Instruction *, 8> Worklist;
+ SmallPtrSet<Instruction *, 8> VisitedInstr;
for (auto &Phi : Header->phis()) {
Value *V = Phi.getIncomingValueForBlock(Latch);
if (Instruction *I = dyn_cast<Instruction>(V))
@@ -151,11 +152,13 @@ static bool processHeaderPhiOperands(BasicBlock *Header, BasicBlock *Latch,
Instruction *I = Worklist.pop_back_val();
if (!Visit(I))
return false;
+ VisitedInstr.insert(I);
if (AftBlocks.count(I->getParent()))
for (auto &U : I->operands())
if (Instruction *II = dyn_cast<Instruction>(U))
- Worklist.push_back(II);
+ if (!VisitedInstr.count(II))
+ Worklist.push_back(II);
}
return true;
@@ -245,7 +248,7 @@ llvm::UnrollAndJamLoop(Loop *L, unsigned Count, unsigned TripCount,
bool CompletelyUnroll = (Count == TripCount);
// We use the runtime remainder in cases where we don't know trip multiple
- if (TripMultiple == 1 || TripMultiple % Count != 0) {
+ if (TripMultiple % Count != 0) {
if (!UnrollRuntimeLoopRemainder(L, Count, /*AllowExpensiveTripCount*/ false,
/*UseEpilogRemainder*/ true,
UnrollRemainder, /*ForgetAllSCEV*/ false,
@@ -346,7 +349,9 @@ llvm::UnrollAndJamLoop(Loop *L, unsigned Count, unsigned TripCount,
LoopBlocksDFS::RPOIterator BlockBegin = DFS.beginRPO();
LoopBlocksDFS::RPOIterator BlockEnd = DFS.endRPO();
- if (Header->getParent()->isDebugInfoForProfiling())
+ // When a FSDiscriminator is enabled, we don't need to add the multiply
+ // factors to the discriminators.
+ if (Header->getParent()->isDebugInfoForProfiling() && !EnableFSDiscriminator)
for (BasicBlock *BB : L->getBlocks())
for (Instruction &I : *BB)
if (!isa<DbgInfoIntrinsic>(&I))
@@ -432,9 +437,8 @@ llvm::UnrollAndJamLoop(Loop *L, unsigned Count, unsigned TripCount,
remapInstructionsInBlocks(NewBlocks, LastValueMap);
for (BasicBlock *NewBlock : NewBlocks) {
for (Instruction &I : *NewBlock) {
- if (auto *II = dyn_cast<IntrinsicInst>(&I))
- if (II->getIntrinsicID() == Intrinsic::assume)
- AC->registerAssumption(II);
+ if (auto *II = dyn_cast<AssumeInst>(&I))
+ AC->registerAssumption(II);
}
}
@@ -831,6 +835,23 @@ static bool isEligibleLoopForm(const Loop &Root) {
if (SubLoopsSize != 1)
return false;
+ // Only loops with a single exit block can be unrolled and jammed.
+ // The function getExitBlock() is used for this check, rather than
+ // getUniqueExitBlock() to ensure loops with mulitple exit edges are
+ // disallowed.
+ if (!L->getExitBlock()) {
+ LLVM_DEBUG(dbgs() << "Won't unroll-and-jam; only loops with single exit "
+ "blocks can be unrolled and jammed.\n");
+ return false;
+ }
+
+ // Only loops with a single exiting block can be unrolled and jammed.
+ if (!L->getExitingBlock()) {
+ LLVM_DEBUG(dbgs() << "Won't unroll-and-jam; only loops with single "
+ "exiting blocks can be unrolled and jammed.\n");
+ return false;
+ }
+
L = L->getSubLoops()[0];
} while (L);