aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Scalar/LoopFuse.cpp
diff options
context:
space:
mode:
authorWhitney Tsang <whitneyt@ca.ibm.com>2020-01-29 15:02:21 +0000
committerWhitney Tsang <whitneyt@ca.ibm.com>2020-01-29 15:06:11 +0000
commitda58e68fdf1ba9efd833f8b46216a6642a139178 (patch)
treeba44c41a8fe5a31342641f45652e0737f8f0177e /llvm/lib/Transforms/Scalar/LoopFuse.cpp
parent0bec0e71514a038f828b147725f44c5ed03a608b (diff)
downloadllvm-da58e68fdf1ba9efd833f8b46216a6642a139178.zip
llvm-da58e68fdf1ba9efd833f8b46216a6642a139178.tar.gz
llvm-da58e68fdf1ba9efd833f8b46216a6642a139178.tar.bz2
[LoopFusion] Move instructions from FC1.Preheader to FC0.Preheader when
proven safe. Summary: Currently LoopFusion give up when the second loop nest preheader is not empty. For example: for (int i = 0; i < 100; ++i) {} x+=1; for (int i = 0; i < 100; ++i) {} The above example should be safe to fuse. This PR moves instructions in FC1 preheader (e.g. x+=1; ) to FC0 preheader, which then LoopFusion is able to fuse them. Reviewer: kbarton, Meinersbur, jdoerfert, dmgreen, fhahn, hfinkel, bmahjour, etiotto Reviewed By: jdoerfert Subscribers: hiraditya, llvm-commits Tag: LLVM Differential Revision: https://reviews.llvm.org/D71821
Diffstat (limited to 'llvm/lib/Transforms/Scalar/LoopFuse.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/LoopFuse.cpp26
1 files changed, 17 insertions, 9 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopFuse.cpp b/llvm/lib/Transforms/Scalar/LoopFuse.cpp
index 430d4bc..24597e2 100644
--- a/llvm/lib/Transforms/Scalar/LoopFuse.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopFuse.cpp
@@ -86,7 +86,9 @@ STATISTIC(UnknownTripCount, "Loop has unknown trip count");
STATISTIC(UncomputableTripCount, "SCEV cannot compute trip count of loop");
STATISTIC(NonEqualTripCount, "Loop trip counts are not the same");
STATISTIC(NonAdjacent, "Loops are not adjacent");
-STATISTIC(NonEmptyPreheader, "Loop has a non-empty preheader");
+STATISTIC(
+ NonEmptyPreheader,
+ "Loop has a non-empty preheader with instructions that cannot be moved");
STATISTIC(FusionNotBeneficial, "Fusion is not beneficial");
STATISTIC(NonIdenticalGuards, "Candidates have different guards");
STATISTIC(NonEmptyExitBlock, "Candidate has a non-empty exit block");
@@ -738,19 +740,21 @@ private:
continue;
}
- // The following three checks look for empty blocks in FC0 and FC1. If
- // any of these blocks are non-empty, we do not fuse. This is done
- // because we currently do not have the safety checks to determine if
- // it is safe to move the blocks past other blocks in the loop. Once
- // these checks are added, these conditions can be relaxed.
- if (!isEmptyPreheader(*FC1)) {
- LLVM_DEBUG(dbgs() << "Fusion candidate does not have empty "
- "preheader. Not fusing.\n");
+ if (!isSafeToMoveBefore(*FC1->Preheader,
+ *FC0->Preheader->getTerminator(), DT, PDT,
+ DI)) {
+ LLVM_DEBUG(dbgs() << "Fusion candidate contains unsafe "
+ "instructions in preheader. Not fusing.\n");
reportLoopFusion<OptimizationRemarkMissed>(*FC0, *FC1,
NonEmptyPreheader);
continue;
}
+ // The following two checks look for empty blocks in FC0 and FC1. If
+ // any of these blocks are non-empty, we do not fuse. This is done
+ // because we currently do not have the safety checks to determine if
+ // it is safe to move the blocks past other blocks in the loop. Once
+ // these checks are added, these conditions can be relaxed.
if (FC0->GuardBranch && !isEmptyExitBlock(*FC0)) {
LLVM_DEBUG(dbgs() << "Fusion candidate does not have empty exit "
"block. Not fusing.\n");
@@ -1166,6 +1170,10 @@ private:
LLVM_DEBUG(dbgs() << "Fusion Candidate 0: \n"; FC0.dump();
dbgs() << "Fusion Candidate 1: \n"; FC1.dump(););
+ // Move instructions from the preheader of FC1 to the end of the preheader
+ // of FC0.
+ moveInstructionsToTheEnd(*FC1.Preheader, *FC0.Preheader, DT, PDT, DI);
+
// Fusing guarded loops is handled slightly differently than non-guarded
// loops and has been broken out into a separate method instead of trying to
// intersperse the logic within a single method.