From f2f00fb11ac2d2708f727f11269c20a3cba75fe5 Mon Sep 17 00:00:00 2001 From: Sanjoy Das Date: Sun, 1 May 2016 04:51:05 +0000 Subject: [PATCH] [SCEV] When printing via -analysis, dump loop disposition There are currently some bugs in tree around SCEV caching an incorrect loop disposition. Printing out loop dispositions will let us write whitebox tests as those are fixed. The dispositions are printed as a list in "inside out" order, i.e. innermost loop first. llvm-svn: 268177 --- llvm/lib/Analysis/ScalarEvolution.cpp | 25 +++++++ .../ScalarEvolution/scev-dispositions.ll | 73 +++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 llvm/test/Analysis/ScalarEvolution/scev-dispositions.ll diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index cfb9f5e24b2e..99c6500e5fca 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -9565,6 +9565,17 @@ static void PrintLoopInfo(raw_ostream &OS, ScalarEvolution *SE, OS << "\n"; } +static StringRef loopDispositionToStr(ScalarEvolution::LoopDisposition LD) { + switch (LD) { + case ScalarEvolution::LoopVariant: + return "Variant"; + case ScalarEvolution::LoopInvariant: + return "Invariant"; + case ScalarEvolution::LoopComputable: + return "Computable"; + } +} + void ScalarEvolution::print(raw_ostream &OS) const { // ScalarEvolution's implementation of the print method is to print // out SCEV values of all instructions that are interesting. Doing @@ -9612,6 +9623,20 @@ void ScalarEvolution::print(raw_ostream &OS) const { } else { OS << *ExitValue; } + + bool First = true; + for (auto *Iter = L; Iter; Iter = Iter->getParentLoop()) { + if (First) { + OS << "\t\t" "LoopDispositions: [ "; + First = false; + } else { + OS << ", "; + } + + OS << loopDispositionToStr(SE.getLoopDisposition(SV, Iter)); + } + + OS << " ]"; } OS << "\n"; diff --git a/llvm/test/Analysis/ScalarEvolution/scev-dispositions.ll b/llvm/test/Analysis/ScalarEvolution/scev-dispositions.ll new file mode 100644 index 000000000000..8f5143930bb8 --- /dev/null +++ b/llvm/test/Analysis/ScalarEvolution/scev-dispositions.ll @@ -0,0 +1,73 @@ +; RUN: opt -analyze -scalar-evolution < %s | FileCheck %s + +define void @single_loop(i32* %buf, i32 %start) { +; CHECK-LABEL: Classifying expressions for: @single_loop + entry: + %val = add i32 %start, 400 + br label %loop + + loop: + %counter = phi i32 [ 0, %entry ], [ %counter.inc, %loop ] + %idx = phi i32 [ %start, %entry ], [ %idx.inc, %loop ] + +; CHECK: %counter = phi i32 [ 0, %entry ], [ %counter.inc, %loop ] +; CHECK-NEXT: --> {{.*}} LoopDispositions: [ Computable ] +; CHECK: %idx = phi i32 [ %start, %entry ], [ %idx.inc, %loop ] +; CHECK-NEXT: --> {{.*}} LoopDispositions: [ Computable ] +; CHECK: %val2 = add i32 %start, 400 +; CHECK-NEXT: --> {{.*}} LoopDispositions: [ Invariant ] +; CHECK: %idx.inc = add nsw i32 %idx, 1 +; CHECK-NEXT: --> {{.*}} LoopDispositions: [ Computable ] +; CHECK: %val3 = load volatile i32, i32* %buf +; CHECK-NEXT: --> {{.*}} LoopDispositions: [ Variant ] + + %val2 = add i32 %start, 400 + %idx.inc = add nsw i32 %idx, 1 + %idx.inc.sext = sext i32 %idx.inc to i64 + %condition = icmp eq i32 %counter, 1 + %counter.inc = add i32 %counter, 1 + %val3 = load volatile i32, i32* %buf + br i1 %condition, label %exit, label %loop + + exit: + ret void +} + + +define void @nested_loop(double* %p, i64 %m) { +; CHECK-LABEL: Classifying expressions for: @nested_loop + +; CHECK: %j = phi i64 [ 0, %entry ], [ %j.next, %outer.latch ] +; CHECK-NEXT: --> {{.*}} LoopDispositions: [ Computable ] +; CHECK: %i = phi i64 [ 0, %outer.loop ], [ %i.next, %bb ] +; CHECK-NEXT: --> {{.*}} LoopDispositions: [ Computable, Variant ] +; CHECK: %j.add = add i64 %j, 100 +; CHECK-NEXT: --> {{.*}} LoopDispositions: [ Invariant, Computable ] +; CHECK: %i.next = add i64 %i, 1 +; CHECK-NEXT: --> {{.*}} LoopDispositions: [ Computable, Variant ] +; CHECK: %j.next = add i64 %j, 91 +; CHECK-NEXT: --> {{.*}} LoopDispositions: [ Computable ] + +entry: + %k = icmp sgt i64 %m, 0 + br i1 %k, label %outer.loop, label %return + +outer.loop: + %j = phi i64 [ 0, %entry ], [ %j.next, %outer.latch ] + br label %bb + +bb: + %i = phi i64 [ 0, %outer.loop ], [ %i.next, %bb ] + %j.add = add i64 %j, 100 + %i.next = add i64 %i, 1 + %exitcond = icmp eq i64 %i.next, 91 + br i1 %exitcond, label %outer.latch, label %bb + +outer.latch: + %j.next = add i64 %j, 91 + %h = icmp eq i64 %j.next, %m + br i1 %h, label %return, label %outer.loop + +return: + ret void +}