[llvm] r278617 - [IRCE] Don't iterate on loops that were cloned out
Sanjoy Das via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 13 18:04:36 PDT 2016
Author: sanjoy
Date: Sat Aug 13 20:04:36 2016
New Revision: 278617
URL: http://llvm.org/viewvc/llvm-project?rev=278617&view=rev
Log:
[IRCE] Don't iterate on loops that were cloned out
IRCE has the ability to further version pre-loops and post-loops that it
created, but this isn't useful at all. This change teaches IRCE to
leave behind some metadata in the loops it creates (by cloning the main
loop) so that these new loops are not re-processed by IRCE.
Today this bug is hidden by another bug -- IRCE does not update LoopInfo
properly so the loop pass manager does not re-invoke IRCE on the loops
it split out. However, once the latter is fixed the bug addressed in
this change causes IRCE to infinite-loop in some cases (e.g. it splits
out a pre-loop, a pre-pre-loop from that, a pre-pre-pre-loop from that
and so on).
Modified:
llvm/trunk/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
llvm/trunk/test/Transforms/IRCE/unhandled.ll
Modified: llvm/trunk/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp?rev=278617&r1=278616&r2=278617&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp Sat Aug 13 20:04:36 2016
@@ -79,6 +79,8 @@ static cl::opt<int> MaxExitProbReciproca
static cl::opt<bool> SkipProfitabilityChecks("irce-skip-profitability-checks",
cl::Hidden, cl::init(false));
+static const char *ClonedLoopTag = "irce.loop.clone";
+
#define DEBUG_TYPE "irce"
namespace {
@@ -630,6 +632,11 @@ LoopStructure::parseLoopStructure(Scalar
BasicBlock *Latch = L.getLoopLatch();
assert(Latch && "Simplified loops only have one latch!");
+ if (Latch->getTerminator()->getMetadata(ClonedLoopTag)) {
+ FailureReason = "loop has already been cloned";
+ return None;
+ }
+
if (!L.isLoopExiting(Latch)) {
FailureReason = "no loop latch";
return None;
@@ -913,6 +920,11 @@ void LoopConstrainer::cloneLoop(LoopCons
return static_cast<Value *>(It->second);
};
+ auto *ClonedLatch =
+ cast<BasicBlock>(GetClonedValue(OriginalLoop.getLoopLatch()));
+ ClonedLatch->getTerminator()->setMetadata(ClonedLoopTag,
+ MDNode::get(Ctx, {}));
+
Result.Structure = MainLoopStructure.map(GetClonedValue);
Result.Structure.Tag = Tag;
Modified: llvm/trunk/test/Transforms/IRCE/unhandled.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IRCE/unhandled.ll?rev=278617&r1=278616&r2=278617&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/IRCE/unhandled.ll (original)
+++ llvm/trunk/test/Transforms/IRCE/unhandled.ll Sat Aug 13 20:04:36 2016
@@ -70,5 +70,30 @@ define void @multiple_latches(i32 *%arr,
ret void
}
+define void @already_cloned(i32 *%arr, i32 *%a_len_ptr, i32 %n) {
+ entry:
+ %len = load i32, i32* %a_len_ptr, !range !0
+ %first.itr.check = icmp sgt i32 %n, 0
+ br i1 %first.itr.check, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ]
+ %idx.next = add i32 %idx, 1
+ %abc = icmp slt i32 %idx, %len
+ br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1
+
+ in.bounds:
+ %addr = getelementptr i32, i32* %arr, i32 %idx
+ store i32 0, i32* %addr
+ %next = icmp slt i32 %idx.next, %n
+ br i1 %next, label %loop, label %exit, !irce.loop.clone !{}
+
+ out.of.bounds:
+ ret void
+
+ exit:
+ ret void
+}
+
!0 = !{i32 0, i32 2147483647}
!1 = !{!"branch_weights", i32 64, i32 4}
More information about the llvm-commits
mailing list