[PATCH] D45754: [PM/LoopUnswitch] Detect irreducible control flow within loops and skip unswitching non-trivial edges.
Chandler Carruth via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 18 14:24:27 PDT 2018
chandlerc updated this revision to Diff 142998.
chandlerc added a comment.
Use the existing facilities and sink this past the point where we find actual
unswitch candidates. This should at least avoid the cost of the loop traversal
when there are no loop invariant conditions.
Repository:
rL LLVM
https://reviews.llvm.org/D45754
Files:
llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll
Index: llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll
===================================================================
--- llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll
+++ llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll
@@ -2350,3 +2350,33 @@
; CHECK-NEXT: %[[LCSSA:.*]] = phi i32 [ %[[V]], %loop_begin ]
; CHECK-NEXT: ret i32 %[[LCSSA]]
}
+
+; Negative test: we do not switch when the loop contains unstructured control
+; flows as it would significantly complicate the process as novel loops might
+; be formed, etc.
+define void @test_no_unswitch_unstructured_cfg(i1* %ptr, i1 %cond) {
+; CHECK-LABEL: @test_no_unswitch_unstructured_cfg(
+entry:
+ br label %loop_begin
+
+loop_begin:
+ br i1 %cond, label %loop_left, label %loop_right
+
+loop_left:
+ %v1 = load i1, i1* %ptr
+ br i1 %v1, label %loop_right, label %loop_merge
+
+loop_right:
+ %v2 = load i1, i1* %ptr
+ br i1 %v2, label %loop_left, label %loop_merge
+
+loop_merge:
+ %v3 = load i1, i1* %ptr
+ br i1 %v3, label %loop_latch, label %loop_exit
+
+loop_latch:
+ br label %loop_begin
+
+loop_exit:
+ ret void
+}
Index: llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
+++ llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
@@ -17,9 +17,11 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/CFG.h"
#include "llvm/Analysis/CodeMetrics.h"
#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/LoopIterator.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constant.h"
@@ -1938,6 +1940,17 @@
if (UnswitchCandidates.empty())
return Changed;
+ // Check if there are irreducible CFG cycles in this loop. If so, we cannot
+ // easily unswitch non-trivial edges out of the loop. Doing so might turn the
+ // irreducible control flow into reducible control flow and introduce new
+ // loops "out of thin air". If we ever discover important use cases for doing
+ // this, we can add support to loop unswitch, but it is a lot of complexit
+ // for what seems little or no real world benifit.
+ LoopBlocksRPO RPOT(&L);
+ RPOT.perform(&LI);
+ if (containsIrreducibleCFG<const BasicBlock *>(RPOT, LI))
+ return Changed;
+
DEBUG(dbgs() << "Considering " << UnswitchCandidates.size()
<< " non-trivial loop invariant conditions for unswitching.\n");
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D45754.142998.patch
Type: text/x-patch
Size: 2612 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180418/b9a5b220/attachment.bin>
More information about the llvm-commits
mailing list