diff options
author | Whitney Tsang <whitneyt@ca.ibm.com> | 2020-01-29 15:02:21 +0000 |
---|---|---|
committer | Whitney Tsang <whitneyt@ca.ibm.com> | 2020-01-29 15:06:11 +0000 |
commit | da58e68fdf1ba9efd833f8b46216a6642a139178 (patch) | |
tree | ba44c41a8fe5a31342641f45652e0737f8f0177e /llvm/lib/Transforms/Scalar/LoopFuse.cpp | |
parent | 0bec0e71514a038f828b147725f44c5ed03a608b (diff) | |
download | llvm-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.cpp | 26 |
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. |