diff options
author | Arkady Shlykov <arkady.shlykov@intel.com> | 2020-01-17 05:35:19 -0800 |
---|---|---|
committer | Arkady Shlykov <arkady.shlykov@intel.com> | 2020-03-02 08:37:11 -0800 |
commit | 3dcaf296aeb0d06bcb8f6e7fb661573d6e01d90c (patch) | |
tree | c61aec0a5c55d6158baeaba941acefdc820ae7f3 /llvm/lib/Transforms/Utils/LoopUnrollPeel.cpp | |
parent | 78f9e5d098af95610f4542ee41479d7931261066 (diff) | |
download | llvm-3dcaf296aeb0d06bcb8f6e7fb661573d6e01d90c.zip llvm-3dcaf296aeb0d06bcb8f6e7fb661573d6e01d90c.tar.gz llvm-3dcaf296aeb0d06bcb8f6e7fb661573d6e01d90c.tar.bz2 |
[Loop Peeling] Add possibility to enable peeling on loop nests.
Summary:
Current peeling implementation bails out in case of loop nests.
The patch introduces a field in TargetTransformInfo structure that
certain targets can use to relax the constraints if it's
profitable (disabled by default).
Also additional option is added to enable peeling manually for
experimenting and testing purposes.
Reviewers: fhahn, lebedev.ri, xbolva00
Reviewed By: xbolva00
Subscribers: RKSimon, xbolva00, hiraditya, zzheng, llvm-commits
Differential Revision: https://reviews.llvm.org/D70304
Diffstat (limited to 'llvm/lib/Transforms/Utils/LoopUnrollPeel.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/LoopUnrollPeel.cpp | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Utils/LoopUnrollPeel.cpp b/llvm/lib/Transforms/Utils/LoopUnrollPeel.cpp index 7a168ff..afc4bbd 100644 --- a/llvm/lib/Transforms/Utils/LoopUnrollPeel.cpp +++ b/llvm/lib/Transforms/Utils/LoopUnrollPeel.cpp @@ -289,8 +289,10 @@ void llvm::computePeelCount(Loop *L, unsigned LoopSize, if (!canPeel(L)) return; - // Only try to peel innermost loops. - if (!L->empty()) + // Only try to peel innermost loops by default. + // The constraint can be relaxed by the target in TTI.getUnrollingPreferences + // or by the flag -unroll-allow-loop-nests-peeling. + if (!UP.AllowLoopNestsPeeling && !L->empty()) return; // If the user provided a peel count, use that. @@ -508,7 +510,10 @@ static void cloneLoopBlocks( BasicBlock *NewBB = CloneBasicBlock(*BB, VMap, ".peel", F); NewBlocks.push_back(NewBB); - if (ParentLoop) + // If an original block is an immediate child of the loop L, its copy + // is a child of a ParentLoop after peeling. If a block is a child of + // a nested loop, it is handled in the cloneLoop() call below. + if (ParentLoop && LI->getLoopFor(*BB) == L) ParentLoop->addBasicBlockToLoop(NewBB, *LI); VMap[*BB] = NewBB; @@ -525,6 +530,12 @@ static void cloneLoopBlocks( } } + // Recursively create the new Loop objects for nested loops, if any, + // to preserve LoopInfo. + for (Loop *ChildLoop : *L) { + cloneLoop(ChildLoop, ParentLoop, VMap, LI, nullptr); + } + // Hook-up the control flow for the newly inserted blocks. // The new header is hooked up directly to the "top", which is either // the original loop preheader (for the first iteration) or the previous |