[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