summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Santiago Aboy Solanes <solanes@google.com> 2022-04-08 18:00:48 +0100
committer Santiago Aboy Solanes <solanes@google.com> 2022-04-14 14:51:30 +0100
commit0eca098c263e3f93d9996dbd6070a53d09d4a6c6 (patch)
treee53180163e8cfcbfc0b8e6b80f45dc60c6bc4c8c
parentd77cf74d29bf53d807b707e5f4da4f7176c08239 (diff)
Enable LoopOptimization for graphs with try catch blocks
We can enable the optimization when the graph has try catch blocks, but we do not perform the optimizations if the loops themselves have try catch blocks. Bug: 227283906 Change-Id: I8889d2ed7a5a260d5c2dcbbc5184cb7eaf3a8f9f
-rw-r--r--compiler/optimizing/loop_optimization.cc107
-rw-r--r--compiler/optimizing/loop_optimization.h18
-rw-r--r--compiler/optimizing/superblock_cloner.cc13
-rw-r--r--test/530-checker-loops-try-catch/expected-stderr.txt0
-rw-r--r--test/530-checker-loops-try-catch/expected-stdout.txt1
-rw-r--r--test/530-checker-loops-try-catch/info.txt1
-rw-r--r--test/530-checker-loops-try-catch/src/Main.java1558
-rw-r--r--test/530-checker-peel-unroll/src/Main.java494
8 files changed, 2076 insertions, 116 deletions
diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc
index 77dfe68bf6..2d7c20825c 100644
--- a/compiler/optimizing/loop_optimization.cc
+++ b/compiler/optimizing/loop_optimization.cc
@@ -491,9 +491,9 @@ HLoopOptimization::HLoopOptimization(HGraph* graph,
}
bool HLoopOptimization::Run() {
- // Skip if there is no loop or the graph has try-catch/irreducible loops.
+ // Skip if there is no loop or the graph has irreducible loops.
// TODO: make this less of a sledgehammer.
- if (!graph_->HasLoops() || graph_->HasTryCatch() || graph_->HasIrreducibleLoops()) {
+ if (!graph_->HasLoops() || graph_->HasIrreducibleLoops()) {
return false;
}
@@ -502,7 +502,7 @@ bool HLoopOptimization::Run() {
loop_allocator_ = &allocator;
// Perform loop optimizations.
- bool didLoopOpt = LocalRun();
+ const bool did_loop_opt = LocalRun();
if (top_loop_ == nullptr) {
graph_->SetHasLoops(false); // no more loops
}
@@ -511,7 +511,7 @@ bool HLoopOptimization::Run() {
loop_allocator_ = nullptr;
last_loop_ = top_loop_ = nullptr;
- return didLoopOpt;
+ return did_loop_opt;
}
//
@@ -519,7 +519,6 @@ bool HLoopOptimization::Run() {
//
bool HLoopOptimization::LocalRun() {
- bool didLoopOpt = false;
// Build the linear order using the phase-local allocator. This step enables building
// a loop hierarchy that properly reflects the outer-inner and previous-next relation.
ScopedArenaVector<HBasicBlock*> linear_order(loop_allocator_->Adapter(kArenaAllocLinearOrder));
@@ -532,34 +531,37 @@ bool HLoopOptimization::LocalRun() {
}
}
+ // TODO(solanes): How can `top_loop_` be null if `graph_->HasLoops()` is true?
+ if (top_loop_ == nullptr) {
+ return false;
+ }
+
// Traverse the loop hierarchy inner-to-outer and optimize. Traversal can use
// temporary data structures using the phase-local allocator. All new HIR
// should use the global allocator.
- if (top_loop_ != nullptr) {
- ScopedArenaSet<HInstruction*> iset(loop_allocator_->Adapter(kArenaAllocLoopOptimization));
- ScopedArenaSafeMap<HInstruction*, HInstruction*> reds(
- std::less<HInstruction*>(), loop_allocator_->Adapter(kArenaAllocLoopOptimization));
- ScopedArenaSet<ArrayReference> refs(loop_allocator_->Adapter(kArenaAllocLoopOptimization));
- ScopedArenaSafeMap<HInstruction*, HInstruction*> map(
- std::less<HInstruction*>(), loop_allocator_->Adapter(kArenaAllocLoopOptimization));
- ScopedArenaSafeMap<HInstruction*, HInstruction*> perm(
- std::less<HInstruction*>(), loop_allocator_->Adapter(kArenaAllocLoopOptimization));
- // Attach.
- iset_ = &iset;
- reductions_ = &reds;
- vector_refs_ = &refs;
- vector_map_ = &map;
- vector_permanent_map_ = &perm;
- // Traverse.
- didLoopOpt = TraverseLoopsInnerToOuter(top_loop_);
- // Detach.
- iset_ = nullptr;
- reductions_ = nullptr;
- vector_refs_ = nullptr;
- vector_map_ = nullptr;
- vector_permanent_map_ = nullptr;
- }
- return didLoopOpt;
+ ScopedArenaSet<HInstruction*> iset(loop_allocator_->Adapter(kArenaAllocLoopOptimization));
+ ScopedArenaSafeMap<HInstruction*, HInstruction*> reds(
+ std::less<HInstruction*>(), loop_allocator_->Adapter(kArenaAllocLoopOptimization));
+ ScopedArenaSet<ArrayReference> refs(loop_allocator_->Adapter(kArenaAllocLoopOptimization));
+ ScopedArenaSafeMap<HInstruction*, HInstruction*> map(
+ std::less<HInstruction*>(), loop_allocator_->Adapter(kArenaAllocLoopOptimization));
+ ScopedArenaSafeMap<HInstruction*, HInstruction*> perm(
+ std::less<HInstruction*>(), loop_allocator_->Adapter(kArenaAllocLoopOptimization));
+ // Attach.
+ iset_ = &iset;
+ reductions_ = &reds;
+ vector_refs_ = &refs;
+ vector_map_ = &map;
+ vector_permanent_map_ = &perm;
+ // Traverse.
+ const bool did_loop_opt = TraverseLoopsInnerToOuter(top_loop_);
+ // Detach.
+ iset_ = nullptr;
+ reductions_ = nullptr;
+ vector_refs_ = nullptr;
+ vector_map_ = nullptr;
+ vector_permanent_map_ = nullptr;
+ return did_loop_opt;
}
void HLoopOptimization::AddLoop(HLoopInformation* loop_info) {
@@ -618,6 +620,18 @@ bool HLoopOptimization::TraverseLoopsInnerToOuter(LoopNode* node) {
induction_range_.ReVisit(node->loop_info);
changed = true;
}
+
+ CalculateAndSetTryCatchKind(node);
+ if (node->try_catch_kind == LoopNode::TryCatchKind::kHasTryCatch) {
+ // The current optimizations assume that the loops do not contain try/catches.
+ // TODO(solanes, 227283906): Assess if we can modify them to work with try/catches.
+ continue;
+ }
+
+ DCHECK(node->try_catch_kind == LoopNode::TryCatchKind::kNoTryCatch)
+ << "kind: " << static_cast<int>(node->try_catch_kind)
+ << ". LoopOptimization requires the loops to not have try catches.";
+
// Repeat simplifications in the loop-body until no more changes occur.
// Note that since each simplification consists of eliminating code (without
// introducing new code), this process is always finite.
@@ -635,6 +649,37 @@ bool HLoopOptimization::TraverseLoopsInnerToOuter(LoopNode* node) {
return changed;
}
+void HLoopOptimization::CalculateAndSetTryCatchKind(LoopNode* node) {
+ DCHECK(node != nullptr);
+ DCHECK(node->try_catch_kind == LoopNode::TryCatchKind::kUnknown)
+ << "kind: " << static_cast<int>(node->try_catch_kind)
+ << ". SetTryCatchKind should be called only once per LoopNode.";
+
+ // If a inner loop has a try catch, then the outer loop has one too (as it contains `inner`).
+ // Knowing this, we could skip iterating through all of the outer loop's parents with a simple
+ // check.
+ for (LoopNode* inner = node->inner; inner != nullptr; inner = inner->next) {
+ DCHECK(inner->try_catch_kind != LoopNode::TryCatchKind::kUnknown)
+ << "kind: " << static_cast<int>(inner->try_catch_kind)
+ << ". Should have updated the inner loop before the outer loop.";
+
+ if (inner->try_catch_kind == LoopNode::TryCatchKind::kHasTryCatch) {
+ node->try_catch_kind = LoopNode::TryCatchKind::kHasTryCatch;
+ return;
+ }
+ }
+
+ for (HBlocksInLoopIterator it_loop(*node->loop_info); !it_loop.Done(); it_loop.Advance()) {
+ HBasicBlock* block = it_loop.Current();
+ if (block->GetTryCatchInformation() != nullptr) {
+ node->try_catch_kind = LoopNode::TryCatchKind::kHasTryCatch;
+ return;
+ }
+ }
+
+ node->try_catch_kind = LoopNode::TryCatchKind::kNoTryCatch;
+}
+
//
// Optimization.
//
@@ -782,8 +827,6 @@ bool HLoopOptimization::OptimizeInnerLoop(LoopNode* node) {
return TryOptimizeInnerLoopFinite(node) || TryPeelingAndUnrolling(node);
}
-
-
//
// Scalar loop peeling and unrolling: generic part methods.
//
diff --git a/compiler/optimizing/loop_optimization.h b/compiler/optimizing/loop_optimization.h
index 3acd5b191b..b17861648f 100644
--- a/compiler/optimizing/loop_optimization.h
+++ b/compiler/optimizing/loop_optimization.h
@@ -57,12 +57,23 @@ class HLoopOptimization : public HOptimization {
outer(nullptr),
inner(nullptr),
previous(nullptr),
- next(nullptr) {}
+ next(nullptr),
+ try_catch_kind(TryCatchKind::kUnknown) {}
+
+ enum class TryCatchKind {
+ kUnknown,
+ // Either if we have a try catch in the loop, or if the loop is inside of an outer try catch,
+ // we set `kHasTryCatch`.
+ kHasTryCatch,
+ kNoTryCatch
+ };
+
HLoopInformation* loop_info;
LoopNode* outer;
LoopNode* inner;
LoopNode* previous;
LoopNode* next;
+ TryCatchKind try_catch_kind;
};
/*
@@ -131,6 +142,11 @@ class HLoopOptimization : public HOptimization {
// Returns true if loops nested inside current loop (node) have changed.
bool TraverseLoopsInnerToOuter(LoopNode* node);
+ // Calculates `node`'s `try_catch_kind` and sets it to:
+ // 1) kHasTryCatch if it has try catches (or if it's inside of an outer try catch)
+ // 2) kNoTryCatch otherwise.
+ void CalculateAndSetTryCatchKind(LoopNode* node);
+
//
// Optimization.
//
diff --git a/compiler/optimizing/superblock_cloner.cc b/compiler/optimizing/superblock_cloner.cc
index b46d193541..a5f919c31c 100644
--- a/compiler/optimizing/superblock_cloner.cc
+++ b/compiler/optimizing/superblock_cloner.cc
@@ -855,11 +855,20 @@ void SuperblockCloner::SetSuccessorRemappingInfo(const HEdgeSet* remap_orig_inte
}
bool SuperblockCloner::IsSubgraphClonable() const {
- // TODO: Support irreducible graphs and graphs with try-catch.
- if (graph_->HasIrreducibleLoops() || graph_->HasTryCatch()) {
+ // TODO: Support irreducible graphs and subgraphs with try-catch.
+ if (graph_->HasIrreducibleLoops()) {
return false;
}
+ for (HBasicBlock* block : graph_->GetReversePostOrder()) {
+ if (!IsInOrigBBSet(block)) {
+ continue;
+ }
+ if (block->GetTryCatchInformation() != nullptr) {
+ return false;
+ }
+ }
+
HInstructionMap live_outs(
std::less<HInstruction*>(), graph_->GetAllocator()->Adapter(kArenaAllocSuperblockCloner));
diff --git a/test/530-checker-loops-try-catch/expected-stderr.txt b/test/530-checker-loops-try-catch/expected-stderr.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/530-checker-loops-try-catch/expected-stderr.txt
diff --git a/test/530-checker-loops-try-catch/expected-stdout.txt b/test/530-checker-loops-try-catch/expected-stdout.txt
new file mode 100644
index 0000000000..b0aad4deb5
--- /dev/null
+++ b/test/530-checker-loops-try-catch/expected-stdout.txt
@@ -0,0 +1 @@
+passed
diff --git a/test/530-checker-loops-try-catch/info.txt b/test/530-checker-loops-try-catch/info.txt
new file mode 100644
index 0000000000..5ff3c22960
--- /dev/null
+++ b/test/530-checker-loops-try-catch/info.txt
@@ -0,0 +1 @@
+Test on loop optimizations, in particular with try catches.
diff --git a/test/530-checker-loops-try-catch/src/Main.java b/test/530-checker-loops-try-catch/src/Main.java
new file mode 100644
index 0000000000..8d44b65662
--- /dev/null
+++ b/test/530-checker-loops-try-catch/src/Main.java
@@ -0,0 +1,1558 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Test on loop optimizations, in particular with try catches.
+//
+public class Main {
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: int Main.$noinline$geo1(int) loop_optimization (before)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: int Main.$noinline$geo1(int) loop_optimization (before)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Mul loop:<<Loop>>
+
+ /// CHECK-START: int Main.$noinline$geo1(int) loop_optimization (after)
+ /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none
+ /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0 loop:none
+ /// CHECK-DAG: <<Int:i\d+>> IntConstant 1410065408 loop:none
+ /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Par>>,<<Int>>] loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Mul>>,<<Zer>>] loop:none
+ /// CHECK-DAG: Return [<<Add>>] loop:none
+
+ /// CHECK-START: int Main.$noinline$geo1(int) loop_optimization (after)
+ /// CHECK-NOT: Phi
+ private static int $noinline$geo1(int a) {
+ for (int i = 0; i < 10; i++) {
+ a *= 10;
+ }
+
+ // Outer try catch does not block loop optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ return a;
+ }
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: int Main.$noinline$geo1_Blocking(int) loop_optimization (before)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: int Main.$noinline$geo1_Blocking(int) loop_optimization (before)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Mul loop:<<Loop>>
+
+ /// CHECK-START: int Main.$noinline$geo1_Blocking(int) loop_optimization (after)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Mul loop:<<Loop>>
+ private static int $noinline$geo1_Blocking(int a) {
+ for (int i = 0; i < 10; i++) {
+ a *= 10;
+
+ // Try catch blocks optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ }
+ return a;
+ }
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: int Main.$noinline$geo2(int) loop_optimization (before)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: int Main.$noinline$geo2(int) loop_optimization (before)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Shl loop:<<Loop>>
+
+ /// CHECK-START: int Main.$noinline$geo2(int) loop_optimization (after)
+ /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none
+ /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0 loop:none
+ /// CHECK-DAG: <<Int:i\d+>> IntConstant 1024 loop:none
+ /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Par>>,<<Int>>] loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Mul>>,<<Zer>>] loop:none
+ /// CHECK-DAG: Return [<<Add>>] loop:none
+
+ /// CHECK-START: int Main.$noinline$geo2(int) loop_optimization (after)
+ /// CHECK-NOT: Phi
+ private static int $noinline$geo2(int a) {
+ for (int i = 0; i < 10; i++) {
+ a <<= 1;
+ }
+
+ // Outer try catch does not block loop optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ return a;
+ }
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: int Main.$noinline$geo2_Blocking(int) loop_optimization (before)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: int Main.$noinline$geo2_Blocking(int) loop_optimization (before)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Shl loop:<<Loop>>
+
+ /// CHECK-START: int Main.$noinline$geo2_Blocking(int) loop_optimization (after)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Shl loop:<<Loop>>
+ private static int $noinline$geo2_Blocking(int a) {
+ for (int i = 0; i < 10; i++) {
+ a <<= 1;
+
+ // Try catch blocks optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ }
+ return a;
+ }
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: int Main.$noinline$geo3(int) loop_optimization (before)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: int Main.$noinline$geo3(int) loop_optimization (before)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Div loop:<<Loop>>
+
+ /// CHECK-START: int Main.$noinline$geo3(int) loop_optimization (after)
+ /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none
+ /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0 loop:none
+ /// CHECK-DAG: <<Int:i\d+>> IntConstant 59049 loop:none
+ /// CHECK-DAG: <<Div:i\d+>> Div [<<Par>>,<<Int>>] loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Div>>,<<Zer>>] loop:none
+ /// CHECK-DAG: Return [<<Add>>] loop:none
+
+ /// CHECK-START: int Main.$noinline$geo3(int) loop_optimization (after)
+ /// CHECK-NOT: Phi
+ private static int $noinline$geo3(int a) {
+ for (int i = 0; i < 10; i++) {
+ a /= 3;
+ }
+
+ // Outer try catch does not block loop optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ return a;
+ }
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: int Main.$noinline$geo3_Blocking(int) loop_optimization (before)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: int Main.$noinline$geo3_Blocking(int) loop_optimization (before)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Div loop:<<Loop>>
+
+ /// CHECK-START: int Main.$noinline$geo3_Blocking(int) loop_optimization (after)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Div loop:<<Loop>>
+ private static int $noinline$geo3_Blocking(int a) {
+ for (int i = 0; i < 10; i++) {
+ a /= 3;
+
+ // Try catch blocks optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ }
+ return a;
+ }
+
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: int Main.$noinline$geo4(int) loop_optimization (before)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: int Main.$noinline$geo4(int) loop_optimization (before)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Rem loop:<<Loop>>
+
+ /// CHECK-START: int Main.$noinline$geo4(int) loop_optimization (after)
+ /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none
+ /// CHECK-DAG: <<Int:i\d+>> IntConstant 7 loop:none
+ /// CHECK-DAG: <<Rem:i\d+>> Rem [<<Par>>,<<Int>>] loop:none
+ /// CHECK-DAG: Return [<<Rem>>] loop:none
+
+ /// CHECK-START: int Main.$noinline$geo4(int) loop_optimization (after)
+ /// CHECK-NOT: Phi
+ private static int $noinline$geo4(int a) {
+ for (int i = 0; i < 10; i++) {
+ a %= 7; // a wrap-around induction
+ }
+
+ // Outer try catch does not block loop optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ return a;
+ }
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: int Main.$noinline$geo4_Blocking(int) loop_optimization (before)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: int Main.$noinline$geo4_Blocking(int) loop_optimization (before)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Rem loop:<<Loop>>
+
+ /// CHECK-START: int Main.$noinline$geo4_Blocking(int) loop_optimization (after)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Rem loop:<<Loop>>
+ private static int $noinline$geo4_Blocking(int a) {
+ for (int i = 0; i < 10; i++) {
+ a %= 7; // a wrap-around induction
+
+ // Try catch blocks optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ }
+ return a;
+ }
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: int Main.$noinline$geo5() loop_optimization (before)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: int Main.$noinline$geo5() loop_optimization (before)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Shr loop:<<Loop>>
+
+ /// CHECK-START: int Main.$noinline$geo5() loop_optimization (after)
+ /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 loop:none
+ /// CHECK-DAG: <<Int1:i\d+>> IntConstant 2147483647 loop:none
+ /// CHECK-DAG: <<Int2:i\d+>> IntConstant 1024 loop:none
+ /// CHECK-DAG: <<Div:i\d+>> Div [<<Int1>>,<<Int2>>] loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Div>>,<<Zero>>] loop:none
+ /// CHECK-DAG: Return [<<Add>>] loop:none
+
+ /// CHECK-START: int Main.$noinline$geo5() loop_optimization (after)
+ /// CHECK-NOT: Phi
+ private static int $noinline$geo5() {
+ int a = 0x7fffffff;
+ for (int i = 0; i < 10; i++) {
+ a >>= 1;
+ }
+
+ // Outer try catch does not block loop optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ return a;
+ }
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: int Main.$noinline$geo5_Blocking() loop_optimization (before)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: int Main.$noinline$geo5_Blocking() loop_optimization (before)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Shr loop:<<Loop>>
+
+ /// CHECK-START: int Main.$noinline$geo5_Blocking() loop_optimization (after)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Shr loop:<<Loop>>
+ private static int $noinline$geo5_Blocking() {
+ int a = 0x7fffffff;
+ for (int i = 0; i < 10; i++) {
+ a >>= 1;
+
+ // Try catch blocks optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ }
+ return a;
+ }
+
+ // Tests taken from 530-checker-loops4
+ private static void $noinline$loops4Tests() {
+ int m = 1410065408;
+ for (int i = -100; i <= 100; i++) {
+ expectEquals(m * i, $noinline$geo1(i));
+ expectEquals(m * i, $noinline$geo1_Blocking(i));
+ }
+ for (int i = 1; i <= 1000000000; i *= 10) {
+ expectEquals(m * i, $noinline$geo1(i));
+ expectEquals(m * i, $noinline$geo1_Blocking(i));
+ expectEquals(-m * i, $noinline$geo1(-i));
+ expectEquals(-m * i, $noinline$geo1_Blocking(-i));
+ }
+
+ for (int i = -100; i <= 100; i++) {
+ expectEquals(i << 10, $noinline$geo2(i));
+ expectEquals(i << 10, $noinline$geo2_Blocking(i));
+ }
+ for (int i = 0; i < 22; i++) {
+ expectEquals(1 << (i + 10), $noinline$geo2(1 << i));
+ expectEquals(1 << (i + 10), $noinline$geo2_Blocking(1 << i));
+ }
+ expectEquals(0x80000400, $noinline$geo2(0x00200001));
+ expectEquals(0x80000400, $noinline$geo2_Blocking(0x00200001));
+ expectEquals(0x00000000, $noinline$geo2(0x00400000));
+ expectEquals(0x00000000, $noinline$geo2_Blocking(0x00400000));
+ expectEquals(0x00000400, $noinline$geo2(0x00400001));
+ expectEquals(0x00000400, $noinline$geo2_Blocking(0x00400001));
+
+ int d = 59049;
+ for (int i = -100; i <= 100; i++) {
+ expectEquals(0, $noinline$geo3(i));
+ expectEquals(0, $noinline$geo3_Blocking(i));
+ }
+ for (int i = 1; i <= 100; i++) {
+ expectEquals(i, $noinline$geo3(i * d));
+ expectEquals(i, $noinline$geo3_Blocking(i * d));
+ expectEquals(i, $noinline$geo3(i * d + 1));
+ expectEquals(i, $noinline$geo3_Blocking(i * d + 1));
+ expectEquals(-i, $noinline$geo3(-i * d));
+ expectEquals(-i, $noinline$geo3_Blocking(-i * d));
+ expectEquals(-i, $noinline$geo3(-i * d - 1));
+ expectEquals(-i, $noinline$geo3_Blocking(-i * d - 1));
+ }
+
+ for (int i = -100; i <= 100; i++) {
+ expectEquals(i % 7, $noinline$geo4(i));
+ expectEquals(i % 7, $noinline$geo4_Blocking(i));
+ }
+
+ expectEquals(0x1fffff, $noinline$geo5());
+ expectEquals(0x1fffff, $noinline$geo5_Blocking());
+ }
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: int Main.$noinline$poly1() loop_optimization (before)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: int Main.$noinline$poly1() loop_optimization (before)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+
+ /// CHECK-START: int Main.$noinline$poly1() loop_optimization (after)
+ /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0 loop:none
+ /// CHECK-DAG: <<Int:i\d+>> IntConstant 55 loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Int>>,<<Zer>>] loop:none
+ /// CHECK-DAG: Return [<<Add>>] loop:none
+
+ /// CHECK-START: int Main.$noinline$poly1() instruction_simplifier$after_bce (after)
+ /// CHECK-DAG: <<Int:i\d+>> IntConstant 55 loop:none
+ /// CHECK-DAG: Return [<<Int>>] loop:none
+
+ /// CHECK-START: int Main.$noinline$poly1() loop_optimization (after)
+ /// CHECK-NOT: Phi
+ private static int $noinline$poly1() {
+ int a = 0;
+ for (int i = 0; i <= 10; i++) {
+ a += i;
+ }
+
+ // Outer try catch does not block loop optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+
+ return a;
+ }
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: int Main.$noinline$poly1_Blocking() loop_optimization (before)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: int Main.$noinline$poly1_Blocking() loop_optimization (before)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+
+ /// CHECK-START: int Main.$noinline$poly1_Blocking() loop_optimization (after)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+ private static int $noinline$poly1_Blocking() {
+ int a = 0;
+ for (int i = 0; i <= 10; i++) {
+ a += i;
+
+ // Try catch blocks optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ }
+
+ return a;
+ }
+
+ // Multiplication in linear induction has been optimized earlier,
+ // but that does not stop the induction variable recognition
+ // and loop optimizer.
+ //
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: int Main.$noinline$poly2(int) loop_optimization (before)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: int Main.$noinline$poly2(int) loop_optimization (before)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Shl loop:<<Loop>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+
+ /// CHECK-START: int Main.$noinline$poly2(int) loop_optimization (after)
+ /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none
+ /// CHECK-DAG: <<Int:i\d+>> IntConstant 185 loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Int>>,<<Par>>] loop:none
+ /// CHECK-DAG: Return [<<Add>>] loop:none
+
+ /// CHECK-START: int Main.$noinline$poly2(int) loop_optimization (after)
+ /// CHECK-NOT: Phi
+ private static int $noinline$poly2(int a) {
+ for (int i = 0; i < 10; i++) {
+ int k = 3 * i + 5;
+ a += k;
+ }
+
+ // Outer try catch does not block loop optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ return a;
+ }
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: int Main.$noinline$poly2_Blocking(int) loop_optimization (before)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: int Main.$noinline$poly2_Blocking(int) loop_optimization (before)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Shl loop:<<Loop>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+
+ /// CHECK-START: int Main.$noinline$poly2_Blocking(int) loop_optimization (after)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Shl loop:<<Loop>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+ private static int $noinline$poly2_Blocking(int a) {
+ for (int i = 0; i < 10; i++) {
+ int k = 3 * i + 5;
+ a += k;
+
+ // Try catch blocks optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ }
+
+ return a;
+ }
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: int Main.$noinline$poly3() loop_optimization (before)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: int Main.$noinline$poly3() loop_optimization (before)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+
+ /// CHECK-START: int Main.$noinline$poly3() loop_optimization (after)
+ /// CHECK-DAG: <<Ini:i\d+>> IntConstant 12345 loop:none
+ /// CHECK-DAG: <<Int:i\d+>> IntConstant -2146736968 loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Int>>,<<Ini>>] loop:none
+ /// CHECK-DAG: Return [<<Add>>] loop:none
+
+ /// CHECK-START: int Main.$noinline$poly3() instruction_simplifier$after_bce (after)
+ /// CHECK-DAG: <<Int:i\d+>> IntConstant -2146724623 loop:none
+ /// CHECK-DAG: Return [<<Int>>] loop:none
+
+ /// CHECK-START: int Main.$noinline$poly3() loop_optimization (after)
+ /// CHECK-NOT: Phi
+ private static int $noinline$poly3() {
+ int a = 12345;
+ for (int i = 0; i <= 10; i++) {
+ a += (2147483646 * i + 67890);
+ }
+
+ // Outer try catch does not block loop optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ return a;
+ }
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: int Main.$noinline$poly3_Blocking() loop_optimization (before)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: int Main.$noinline$poly3_Blocking() loop_optimization (before)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+
+ /// CHECK-START: int Main.$noinline$poly3_Blocking() loop_optimization (after)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+ /// CHECK-DAG: Add loop:<<Loop>>
+ private static int $noinline$poly3_Blocking() {
+ int a = 12345;
+ for (int i = 0; i <= 10; i++) {
+ a += (2147483646 * i + 67890);
+
+ // Try catch blocks optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ }
+ return a;
+ }
+
+ // Tests taken from 530-checker-loops5
+ private static void $noinline$loops5Tests() {
+ expectEquals(55, $noinline$poly1());
+ expectEquals(55, $noinline$poly1_Blocking());
+ expectEquals(185, $noinline$poly2(0));
+ expectEquals(185, $noinline$poly2_Blocking(0));
+ expectEquals(192, $noinline$poly2(7));
+ expectEquals(192, $noinline$poly2_Blocking(7));
+ expectEquals(-2146724623, $noinline$poly3());
+ expectEquals(-2146724623, $noinline$poly3_Blocking());
+ }
+
+ // Constants used for peel unroll tests.
+ private static final int LENGTH = 4 * 1024;
+ private static final int RESULT_POS = 4;
+
+ private static final void initIntArray(int[] a) {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = i % 4;
+ }
+ }
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (after)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (before)
+ /// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi>>,<<Limit>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get0:i\d+>> ArrayGet [<<Array>>,<<Phi>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Get0>>,<<Get1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [<<Array>>,<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none
+
+ /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (before)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (before)
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
+
+ /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (after)
+ /// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi>>,<<Limit>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get0:i\d+>> ArrayGet [<<Array>>,<<Phi>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Get0>>,<<Get1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [<<Array>>,<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-DAG: <<CheckA:z\d+>> GreaterThanOrEqual [<<IndAdd>>,<<Limit>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<IfA:v\d+>> If [<<Const0>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get0A:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<IndAddA:i\d+>> Add [<<IndAdd>>,<<Const1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get1A:i\d+>> ArrayGet [<<Array>>,<<IndAddA>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<AddA:i\d+>> Add [<<Get0A>>,<<Get1A>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [<<Array>>,<<IndAdd>>,<<AddA>>] loop:<<Loop>> outer_loop:none
+
+ /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (after)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (after)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
+ private static final void $noinline$unrollingLoadStoreElimination(int[] a) {
+ for (int i = 0; i < LENGTH - 2; i++) {
+ a[i] += a[i + 1];
+ }
+
+ // Outer try catch does not block loop optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ }
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (after)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (before)
+ /// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi>>,<<Limit>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get0:i\d+>> ArrayGet [<<Array>>,<<Phi>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Get0>>,<<Get1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [<<Array>>,<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none
+
+ /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (before)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (before)
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
+
+ /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (after)
+ /// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi>>,<<Limit>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get0:i\d+>> ArrayGet [<<Array>>,<<Phi>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Get0>>,<<Get1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [<<Array>>,<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none
+
+ /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (after)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (after)
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
+ private static final void $noinline$unrollingLoadStoreElimination_Blocking(int[] a) {
+ for (int i = 0; i < LENGTH - 2; i++) {
+ a[i] += a[i + 1];
+
+ // Try catch blocks optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ }
+ }
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (before)
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
+ /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: If [<<Check>>] loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop2>>
+
+ // Each one of the three `for` loops has an `if`. The try catch has the 4th `if`.
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (before)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK-NOT: If
+
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (before)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (before)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
+
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after)
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
+ /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: If [<<Check>>] loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: <<AddI:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop2>>
+ //
+ /// CHECK-DAG: If [<<Const0>>] loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
+
+ // Loop unrolling adds a 5th `if`. It is the one with `Const0` above.
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK-NOT: If
+
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
+ private static final void $noinline$unrollingInTheNest(int[] a, int[] b, int x) {
+ for (int k = 0; k < 16; k++) {
+ for (int j = 0; j < 16; j++) {
+ for (int i = 0; i < 128; i++) {
+ b[x]++;
+ a[i] = a[i] + 1;
+ }
+ }
+ }
+
+ // Outer try catch does not block loop optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ }
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (before)
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
+ /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: If [<<Check>>] loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
+ //
+ /// CHECK-DAG: Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop2>>
+
+ // Each one of the three `for` loops has an `if`. The try catch has the 4th `if`.
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (before)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK-NOT: If
+
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (before)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (before)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
+
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after)
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
+ /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: If [<<Check>>] loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
+ //
+ /// CHECK-DAG: Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop2>>
+
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK-NOT: If
+
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
+ private static final void $noinline$unrollingInTheNest_Blocking(int[] a, int[] b, int x) {
+ for (int k = 0; k < 16; k++) {
+ for (int j = 0; j < 16; j++) {
+ for (int i = 0; i < 128; i++) {
+ b[x]++;
+ a[i] = a[i] + 1;
+
+ // Try catch blocks optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ }
+ }
+ }
+ }
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (before)
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
+ /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: If [<<Check>>] loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
+ //
+ /// CHECK-DAG: Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop2>>
+
+ // Each one of the three `for` loops has an `if`. The try catch has the 4th `if`.
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (before)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK-NOT: If
+
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (before)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (before)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
+
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after)
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
+ /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: If [<<Check>>] loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: <<AddI:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop2>>
+ //
+ /// CHECK-DAG: If [<<Const0>>] loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
+
+ // Loop unrolling adds a 5th `if`. It is the one with `Const0` above.
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK-NOT: If
+
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
+ private static final void $noinline$unrollingInTheNest_TryCatchNotBlocking(int[] a, int[] b, int x) {
+ for (int k = 0; k < 16; k++) {
+ for (int j = 0; j < 16; j++) {
+ for (int i = 0; i < 128; i++) {
+ b[x]++;
+ a[i] = a[i] + 1;
+ }
+ // Try catch does not block the optimization in the innermost loop.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ }
+ }
+ }
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before)
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
+ /// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none
+ /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
+ //
+ /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ //
+ /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+
+ // Each one of the three `for` loops has an `if`. Plus an `if` inside the outer `for`. The try catch has the 5th `if`.
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK-NOT: If
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
+ /// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none
+ /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
+ //
+ /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: If [<<Const0>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: Add [<<AddI2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ //
+ /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: If [<<Const0>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: Add [<<AddI3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+
+ // LoopOptimization adds two `if`s. One for each loop unrolling.
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK-NOT: If
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
+ private static final void $noinline$unrollingTwoLoopsInTheNest(int[] a, int[] b, int x) {
+ for (int k = 0; k < 128; k++) {
+ if (x > 100) {
+ for (int j = 0; j < 128; j++) {
+ a[x]++;
+ }
+ } else {
+ for (int i = 0; i < 128; i++) {
+ b[x]++;
+ }
+ }
+ }
+
+ // Outer try catch does not block loop optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ }
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (before)
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
+ /// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none
+ /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
+ //
+ /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>>
+ //
+ /// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ //
+ /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+
+ // Each one of the three `for` loops has an `if`. Plus an `if` inside the outer `for`. The try catch has the 5th `if`.
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (before)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK-NOT: If
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (before)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (before)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after)
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
+ /// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none
+ /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
+ //
+ /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>>
+ //
+ // Unrelated to the optimization itself, the try catch has an if.
+ /// CHECK-DAG: <<Get:z\d+>> StaticFieldGet field_name:Main.doThrow
+ /// CHECK-DAG: If [<<Get>>]
+ //
+ /// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ //
+ /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: If [<<Const0>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: Add [<<AddI3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+
+ // LoopOptimization adds two `if`s. One for each loop unrolling.
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK-NOT: If
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
+ private static final void $noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[] a, int[] b, int x) {
+ for (int k = 0; k < 128; k++) {
+ if (x > 100) {
+ for (int j = 0; j < 128; j++) {
+ a[x]++;
+ // Try catch blocks optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ }
+ } else {
+ for (int i = 0; i < 128; i++) {
+ b[x]++;
+ }
+ }
+ }
+ }
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (before)
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
+ /// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none
+ /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
+ //
+ /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ //
+ /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>>
+ //
+ /// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+
+ // Each one of the three `for` loops has an `if`. Plus an `if` inside the outer `for`. The try catch has the 5th `if`.
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (before)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK-NOT: If
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (before)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (before)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after)
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
+ /// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none
+ /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
+ //
+ /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: If [<<Const0>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: Add [<<AddI2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ //
+ /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>>
+ //
+ /// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+
+ // LoopOptimization adds two `if`s. One for each loop unrolling.
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK-NOT: If
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
+ private static final void $noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[] a, int[] b, int x) {
+ for (int k = 0; k < 128; k++) {
+ if (x > 100) {
+ for (int j = 0; j < 128; j++) {
+ a[x]++;
+ }
+ } else {
+ for (int i = 0; i < 128; i++) {
+ b[x]++;
+ // Try catch blocks optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ }
+ }
+ }
+ }
+
+ // Consistency check to see we haven't eliminated the try/catch.
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after)
+ /// CHECK: TryBoundary
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (before)
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
+ /// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none
+ /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
+ //
+ /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>>
+ //
+ /// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ //
+ /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>>
+ //
+ /// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+
+ // Each one of the three `for` loops has an `if`. Plus an `if` inside the outer `for`. The try catchs have the 5th and 6th `if`.
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (before)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK-NOT: If
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (before)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (before)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after)
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
+ /// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none
+ /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
+ //
+ /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>>
+ //
+ // Unrelated to the optimization itself, the try catch has an if.
+ /// CHECK-DAG: <<Get1:z\d+>> StaticFieldGet field_name:Main.doThrow
+ /// CHECK-DAG: If [<<Get1>>]
+ //
+ /// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>>
+ //
+ /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>>
+ /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>>
+ //
+ /// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>>
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK-NOT: If
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
+ private static final void $noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[] a, int[] b, int x) {
+ for (int k = 0; k < 128; k++) {
+ if (x > 100) {
+ for (int j = 0; j < 128; j++) {
+ a[x]++;
+ // Try catch blocks optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ }
+ } else {
+ for (int i = 0; i < 128; i++) {
+ b[x]++;
+ // Try catch blocks optimizations.
+ try {
+ if (doThrow) {
+ $noinline$unreachable();
+ }
+ } catch (Error e) {
+ System.out.println("Not expected");
+ }
+ }
+ }
+ }
+ }
+
+ // Tests taken from 530-checker-peel-unroll
+ private static void $noinline$peelUnrollTests() {
+ int[] a = new int[LENGTH];
+ int[] b = new int[LENGTH];
+ initIntArray(a);
+ initIntArray(b);
+
+ $noinline$unrollingLoadStoreElimination(a);
+ $noinline$unrollingLoadStoreElimination_Blocking(a);
+ $noinline$unrollingInTheNest(a, b, RESULT_POS);
+ $noinline$unrollingInTheNest_Blocking(a, b, RESULT_POS);
+ $noinline$unrollingInTheNest_TryCatchNotBlocking(a, b, RESULT_POS);
+ $noinline$unrollingTwoLoopsInTheNest(a, b, RESULT_POS);
+ $noinline$unrollingTwoLoopsInTheNest_OneBlocking(a, b, RESULT_POS);
+ $noinline$unrollingTwoLoopsInTheNest_OtherBlocking(a, b, RESULT_POS);
+ $noinline$unrollingTwoLoopsInTheNest_BothBlocking(a, b, RESULT_POS);
+ }
+
+ public static void main(String[] args) {
+ // Use existing tests to show that the difference between having a try catch inside or outside
+ // the loop.
+ $noinline$loops4Tests();
+ $noinline$loops5Tests();
+ $noinline$peelUnrollTests();
+
+ System.out.println("passed");
+ }
+
+ private static void expectEquals(int expected, int result) {
+ if (expected != result) {
+ throw new Error("Expected: " + expected + ", found: " + result);
+ }
+ }
+
+ private static void $noinline$unreachable() {
+ throw new Error("Unreachable");
+ }
+
+ private static boolean doThrow = false;
+}
diff --git a/test/530-checker-peel-unroll/src/Main.java b/test/530-checker-peel-unroll/src/Main.java
index aee32b7531..f909af3160 100644
--- a/test/530-checker-peel-unroll/src/Main.java
+++ b/test/530-checker-peel-unroll/src/Main.java
@@ -78,9 +78,15 @@ public class Main {
/// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<Add:i\d+>> Add [<<Get0>>,<<Get1>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet [<<Array>>,<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none
- /// CHECK-NOT: ArraySet loop:<<Loop>> outer_loop:none
+
+ /// CHECK-START: void Main.unrollingLoadStoreElimination(int[]) loop_optimization (before)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.unrollingLoadStoreElimination(int[]) loop_optimization (before)
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
/// CHECK-START: void Main.unrollingLoadStoreElimination(int[]) loop_optimization (after)
/// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none
@@ -103,9 +109,18 @@ public class Main {
/// CHECK-DAG: <<Get1A:i\d+>> ArrayGet [<<Array>>,<<IndAddA>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<AddA:i\d+>> Add [<<Get0A>>,<<Get1A>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet [<<Array>>,<<IndAdd>>,<<AddA>>] loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none
- /// CHECK-NOT: ArraySet loop:<<Loop>> outer_loop:none
+
+ /// CHECK-START: void Main.unrollingLoadStoreElimination(int[]) loop_optimization (after)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.unrollingLoadStoreElimination(int[]) loop_optimization (after)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
private static final void unrollingLoadStoreElimination(int[] a) {
for (int i = 0; i < LENGTH - 2; i++) {
a[i] += a[i + 1];
@@ -124,9 +139,14 @@ public class Main {
/// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: Add [<<PhiI>>,<<Const1>>] loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none
- /// CHECK-NOT: ArraySet loop:<<Loop>> outer_loop:none
+
+ /// CHECK-START: void Main.unrollingSwitch(int[]) loop_optimization (before)
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.unrollingSwitch(int[]) loop_optimization (before)
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
/// CHECK-START: void Main.unrollingSwitch(int[]) loop_optimization (after)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
@@ -144,9 +164,16 @@ public class Main {
/// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: Add [<<AddI>>,<<Const1>>] loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none
- /// CHECK-NOT: ArraySet loop:<<Loop>> outer_loop:none
+
+ /// CHECK-START: void Main.unrollingSwitch(int[]) loop_optimization (after)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.unrollingSwitch(int[]) loop_optimization (after)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
private static final void unrollingSwitch(int[] a) {
for (int i = 0; i < LENGTH; i++) {
switch (i % 3) {
@@ -173,9 +200,16 @@ public class Main {
/// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: Add [<<PhiI>>,<<Const1>>] loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none
- /// CHECK-NOT: ArraySet loop:<<Loop>> outer_loop:none
+
+ /// CHECK-START: void Main.unrollingSwapElements(int[]) loop_optimization (before)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.unrollingSwapElements(int[]) loop_optimization (before)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
/// CHECK-START: void Main.unrollingSwapElements(int[]) loop_optimization (after)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
@@ -197,9 +231,20 @@ public class Main {
/// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: Add [<<AddI>>,<<Const1>>] loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none
- /// CHECK-NOT: ArraySet loop:<<Loop>> outer_loop:none
+
+ /// CHECK-START: void Main.unrollingSwapElements(int[]) loop_optimization (after)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.unrollingSwapElements(int[]) loop_optimization (after)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
private static final void unrollingSwapElements(int[] array) {
for (int i = 0; i < LENGTH - 2; i++) {
if (array[i] > array[i + 1]) {
@@ -225,9 +270,21 @@ public class Main {
/// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: Add [<<PhiI>>,<<Const1>>] loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none
- /// CHECK-NOT: ArraySet loop:<<Loop>> outer_loop:none
+
+ // We have two other `ArrayGet` before the `If` that appears in the CHECK-DAG above.
+ /// CHECK-START: void Main.unrollingRInnerproduct(double[][], double[][], double[][], int, int) loop_optimization (before)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.unrollingRInnerproduct(double[][], double[][], double[][], int, int) loop_optimization (before)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
/// CHECK-START: void Main.unrollingRInnerproduct(double[][], double[][], double[][], int, int) loop_optimization (after)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
@@ -251,9 +308,25 @@ public class Main {
/// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: Add [<<AddI>>,<<Const1>>] loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none
- /// CHECK-NOT: ArraySet loop:<<Loop>> outer_loop:none
+
+ /// CHECK-START: void Main.unrollingRInnerproduct(double[][], double[][], double[][], int, int) loop_optimization (after)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.unrollingRInnerproduct(double[][], double[][], double[][], int, int) loop_optimization (after)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
private static final void unrollingRInnerproduct(double[][] result,
double[][] a,
double[][] b,
@@ -284,11 +357,24 @@ public class Main {
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop2>>
- //
- /// CHECK-NOT: ArrayGet
- /// CHECK-NOT: ArraySet
+
+ // Each one of the three `for` loops has an `if`.
+ /// CHECK-START: void Main.unrollingInTheNest(int[], int[], int) loop_optimization (before)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
/// CHECK-NOT: If
+ /// CHECK-START: void Main.unrollingInTheNest(int[], int[], int) loop_optimization (before)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.unrollingInTheNest(int[], int[], int) loop_optimization (before)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
+
/// CHECK-START: void Main.unrollingInTheNest(int[], int[], int) loop_optimization (after)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
@@ -309,10 +395,28 @@ public class Main {
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
- //
- /// CHECK-NOT: ArrayGet
- /// CHECK-NOT: ArraySet
+
+ // Loop unrolling adds a 4th `if`. It is the one with `Const0` above.
+ /// CHECK-START: void Main.unrollingInTheNest(int[], int[], int) loop_optimization (after)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
/// CHECK-NOT: If
+
+ /// CHECK-START: void Main.unrollingInTheNest(int[], int[], int) loop_optimization (after)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.unrollingInTheNest(int[], int[], int) loop_optimization (after)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
private static final void unrollingInTheNest(int[] a, int[] b, int x) {
for (int k = 0; k < 16; k++) {
for (int j = 0; j < 16; j++) {
@@ -349,11 +453,25 @@ public class Main {
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>>
- //
- /// CHECK-NOT: ArrayGet
- /// CHECK-NOT: ArraySet
+
+ // Each one of the three `for` loops has an `if`. Plus an `if` inside the outer `for`.
+ /// CHECK-START: void Main.unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
/// CHECK-NOT: If
+ /// CHECK-START: void Main.unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
+
/// CHECK-START: void Main.unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
@@ -382,10 +500,30 @@ public class Main {
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: Add [<<AddI3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>>
- //
- /// CHECK-NOT: ArrayGet
- /// CHECK-NOT: ArraySet
+
+ // LoopOptimization adds two `if`s. One for each loop unrolling.
+ /// CHECK-START: void Main.unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
/// CHECK-NOT: If
+
+ /// CHECK-START: void Main.unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
private static final void unrollingTwoLoopsInTheNest(int[] a, int[] b, int x) {
for (int k = 0; k < 128; k++) {
if (x > 100) {
@@ -423,7 +561,14 @@ public class Main {
/// CHECK-DAG: <<ZCheck:i\d+>> DivZeroCheck [<<STAdd>>] env:[[<<PhiS>>,<<PhiT>>,<<STAdd>>,<<Const1>>,_,<<Array>>]] loop:none
/// CHECK-DAG: <<Div:i\d+>> Div [<<Const1>>,<<ZCheck>>] loop:none
/// CHECK-DAG: Return [<<Div>>] loop:none
+
+ /// CHECK-START: int Main.unrollingSimpleLiveOuts(int[]) loop_optimization (before)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: int Main.unrollingSimpleLiveOuts(int[]) loop_optimization (before)
+ /// CHECK: ArraySet
/// CHECK-NOT: ArraySet
/// CHECK-START: int Main.unrollingSimpleLiveOuts(int[]) loop_optimization (after)
@@ -461,8 +606,17 @@ public class Main {
/// CHECK-DAG: <<ZCheck:i\d+>> DivZeroCheck [<<STAdd>>] env:[[<<RetPhiS>>,<<RetPhiT>>,<<STAdd>>,<<Const1>>,_,<<Array>>]] loop:none
/// CHECK-DAG: <<Div:i\d+>> Div [<<Const1>>,<<ZCheck>>] loop:none
/// CHECK-DAG: Return [<<Div>>] loop:none
- //
+
+ /// CHECK-START: int Main.unrollingSimpleLiveOuts(int[]) loop_optimization (after)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: int Main.unrollingSimpleLiveOuts(int[]) loop_optimization (after)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
/// CHECK-NOT: ArraySet
private static final int unrollingSimpleLiveOuts(int[] a) {
int s = 1;
@@ -502,8 +656,14 @@ public class Main {
/// CHECK-DAG: ArraySet [<<Array>>,<<PhiI>>,<<AddArr>>] loop:<<Loop1>> outer_loop:<<Loop0>>
//
/// CHECK-DAG: Add [<<OutPhiJ>>,<<Const1>>] loop:<<Loop0>> outer_loop:none
- //
+
+ /// CHECK-START: int Main.unrollingLiveOutsNested(int[]) loop_optimization (before)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: int Main.unrollingLiveOutsNested(int[]) loop_optimization (before)
+ /// CHECK: ArraySet
/// CHECK-NOT: ArraySet
/// CHECK-START: int Main.unrollingLiveOutsNested(int[]) loop_optimization (after)
@@ -545,8 +705,17 @@ public class Main {
//
/// CHECK-DAG: <<RetAdd:i\d+>> Add [<<OutPhiS>>,<<OutPhiT>>] loop:none
/// CHECK-DAG: Return [<<RetAdd>>] loop:none
- //
+
+ /// CHECK-START: int Main.unrollingLiveOutsNested(int[]) loop_optimization (after)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: int Main.unrollingLiveOutsNested(int[]) loop_optimization (after)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
/// CHECK-NOT: ArraySet
private static final int unrollingLiveOutsNested(int[] a) {
int s = 1;
@@ -566,16 +735,21 @@ public class Main {
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none
/// CHECK-DAG: InstanceOf loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: InstanceOf
+
+ /// CHECK-START: void Main.unrollingInstanceOf(int[], java.lang.Object[]) loop_optimization (before)
+ /// CHECK: InstanceOf
+ /// CHECK-NOT: InstanceOf
/// CHECK-START: void Main.unrollingInstanceOf(int[], java.lang.Object[]) loop_optimization (after)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none
/// CHECK-DAG: InstanceOf loop:<<Loop>> outer_loop:none
/// CHECK-DAG: InstanceOf loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: InstanceOf
+
+ /// CHECK-START: void Main.unrollingInstanceOf(int[], java.lang.Object[]) loop_optimization (after)
+ /// CHECK: InstanceOf
+ /// CHECK: InstanceOf
+ /// CHECK-NOT: InstanceOf
public void unrollingInstanceOf(int[] a, Object[] obj_array) {
for (int i = 0; i < LENGTH_B; i++) {
if (obj_array[i] instanceof Integer) {
@@ -588,16 +762,21 @@ public class Main {
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none
/// CHECK-DAG: DivZeroCheck loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: DivZeroCheck
+
+ /// CHECK-START: void Main.unrollingDivZeroCheck(int[], int) loop_optimization (before)
+ /// CHECK: DivZeroCheck
+ /// CHECK-NOT: DivZeroCheck
/// CHECK-START: void Main.unrollingDivZeroCheck(int[], int) loop_optimization (after)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none
/// CHECK-DAG: DivZeroCheck loop:<<Loop>> outer_loop:none
/// CHECK-DAG: DivZeroCheck loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: DivZeroCheck
+
+ /// CHECK-START: void Main.unrollingDivZeroCheck(int[], int) loop_optimization (after)
+ /// CHECK: DivZeroCheck
+ /// CHECK: DivZeroCheck
+ /// CHECK-NOT: DivZeroCheck
public void unrollingDivZeroCheck(int[] a, int r) {
for (int i = 0; i < LENGTH_B; i++) {
a[i] += a[i] / r;
@@ -608,16 +787,21 @@ public class Main {
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none
/// CHECK-DAG: TypeConversion loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: TypeConversion
+
+ /// CHECK-START: void Main.unrollingTypeConversion(int[], double[]) loop_optimization (before)
+ /// CHECK: TypeConversion
+ /// CHECK-NOT: TypeConversion
/// CHECK-START: void Main.unrollingTypeConversion(int[], double[]) loop_optimization (after)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none
/// CHECK-DAG: TypeConversion loop:<<Loop>> outer_loop:none
/// CHECK-DAG: TypeConversion loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: TypeConversion
+
+ /// CHECK-START: void Main.unrollingTypeConversion(int[], double[]) loop_optimization (after)
+ /// CHECK: TypeConversion
+ /// CHECK: TypeConversion
+ /// CHECK-NOT: TypeConversion
public void unrollingTypeConversion(int[] a, double[] b) {
for (int i = 0; i < LENGTH_B; i++) {
a[i] = (int) b[i];
@@ -634,16 +818,21 @@ public class Main {
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none
/// CHECK-DAG: CheckCast loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: CheckCast
+
+ /// CHECK-START: void Main.unrollingCheckCast(int[], java.lang.Object) loop_optimization (before)
+ /// CHECK: CheckCast
+ /// CHECK-NOT: CheckCast
/// CHECK-START: void Main.unrollingCheckCast(int[], java.lang.Object) loop_optimization (after)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none
/// CHECK-DAG: CheckCast loop:<<Loop>> outer_loop:none
/// CHECK-DAG: CheckCast loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: CheckCast
+
+ /// CHECK-START: void Main.unrollingCheckCast(int[], java.lang.Object) loop_optimization (after)
+ /// CHECK: CheckCast
+ /// CHECK: CheckCast
+ /// CHECK-NOT: CheckCast
public void unrollingCheckCast(int[] a, Object o) {
for (int i = 0; i < LENGTH_B; i++) {
if (((SubMain)o) == o) {
@@ -664,10 +853,22 @@ public class Main {
/// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<Add:i\d+>> Add [<<Get0>>,<<Get1>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet [<<Array>>,<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none
- //
+
+ /// CHECK-START: void Main.noUnrollingOddTripCount(int[]) loop_optimization (before)
+ /// CHECK: Phi
/// CHECK-NOT: Phi
+
+ /// CHECK-START: void Main.noUnrollingOddTripCount(int[]) loop_optimization (before)
+ /// CHECK: If
/// CHECK-NOT: If
+
+ /// CHECK-START: void Main.noUnrollingOddTripCount(int[]) loop_optimization (before)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.noUnrollingOddTripCount(int[]) loop_optimization (before)
+ /// CHECK: ArraySet
/// CHECK-NOT: ArraySet
/// CHECK-START: void Main.noUnrollingOddTripCount(int[]) loop_optimization (after)
@@ -676,10 +877,22 @@ public class Main {
/// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
- //
+
+ /// CHECK-START: void Main.noUnrollingOddTripCount(int[]) loop_optimization (after)
+ /// CHECK: Phi
/// CHECK-NOT: Phi
+
+ /// CHECK-START: void Main.noUnrollingOddTripCount(int[]) loop_optimization (after)
+ /// CHECK: If
/// CHECK-NOT: If
+
+ /// CHECK-START: void Main.noUnrollingOddTripCount(int[]) loop_optimization (after)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.noUnrollingOddTripCount(int[]) loop_optimization (after)
+ /// CHECK: ArraySet
/// CHECK-NOT: ArraySet
private static final void noUnrollingOddTripCount(int[] a) {
for (int i = 0; i < LENGTH - 1; i++) {
@@ -699,9 +912,24 @@ public class Main {
/// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<Add:i\d+>> Add [<<Get0>>,<<Get1>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet [<<Array>>,<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none
- //
+
+ /// CHECK-START: void Main.noUnrollingNotKnownTripCount(int[], int) loop_optimization (before)
+ /// CHECK: Phi
/// CHECK-NOT: Phi
+
+ // One `if` for the `for` loop, and another one for a deoptimize.
+ /// CHECK-START: void Main.noUnrollingNotKnownTripCount(int[], int) loop_optimization (before)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK-NOT: If
+
+ /// CHECK-START: void Main.noUnrollingNotKnownTripCount(int[], int) loop_optimization (before)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.noUnrollingNotKnownTripCount(int[], int) loop_optimization (before)
+ /// CHECK: ArraySet
/// CHECK-NOT: ArraySet
/// CHECK-START: void Main.noUnrollingNotKnownTripCount(int[], int) loop_optimization (after)
@@ -710,9 +938,23 @@ public class Main {
/// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
- //
+
+ /// CHECK-START: void Main.noUnrollingNotKnownTripCount(int[], int) loop_optimization (after)
+ /// CHECK: Phi
/// CHECK-NOT: Phi
+
+ /// CHECK-START: void Main.noUnrollingNotKnownTripCount(int[], int) loop_optimization (after)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK-NOT: If
+
+ /// CHECK-START: void Main.noUnrollingNotKnownTripCount(int[], int) loop_optimization (after)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.noUnrollingNotKnownTripCount(int[], int) loop_optimization (after)
+ /// CHECK: ArraySet
/// CHECK-NOT: ArraySet
private static final void noUnrollingNotKnownTripCount(int[] a, int n) {
for (int i = 0; i < n; i++) {
@@ -732,9 +974,15 @@ public class Main {
/// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: If
- /// CHECK-NOT: ArraySet
+
+ /// CHECK-START: void Main.peelingSimple(int[], boolean) loop_optimization (before)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK-NOT: If
+
+ /// CHECK-START: void Main.peelingSimple(int[], boolean) loop_optimization (before)
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
/// CHECK-START: void Main.peelingSimple(int[], boolean) loop_optimization (after)
/// CHECK-DAG: <<Param:z\d+>> ParameterValue loop:none
@@ -754,9 +1002,18 @@ public class Main {
/// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: If
- /// CHECK-NOT: ArraySet
+
+ /// CHECK-START: void Main.peelingSimple(int[], boolean) loop_optimization (after)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK-NOT: If
+
+ /// CHECK-START: void Main.peelingSimple(int[], boolean) loop_optimization (after)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
/// CHECK-START: void Main.peelingSimple(int[], boolean) dead_code_elimination$final (after)
/// CHECK-DAG: <<Param:z\d+>> ParameterValue loop:none
@@ -772,11 +1029,25 @@ public class Main {
/// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: GreaterThanOrEqual
- /// CHECK-NOT: If
- /// CHECK-NOT: ArrayGet
- /// CHECK-NOT: ArraySet
+
+ /// CHECK-START: void Main.peelingSimple(int[], boolean) dead_code_elimination$final (after)
+ /// CHECK: GreaterThanOrEqual
+ /// CHECK-NOT: GreaterThanOrEqual
+
+ /// CHECK-START: void Main.peelingSimple(int[], boolean) dead_code_elimination$final (after)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK-NOT: If
+
+ /// CHECK-START: void Main.peelingSimple(int[], boolean) dead_code_elimination$final (after)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.peelingSimple(int[], boolean) dead_code_elimination$final (after)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK-NOT: ArraySet
private static final void peelingSimple(int[] a, boolean f) {
for (int i = 0; i < LENGTH; i++) {
if (f) {
@@ -808,8 +1079,13 @@ public class Main {
/// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi>>,{{i\d+}}] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: If [<<Check>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: If [<<Eq>>] loop:<<Loop>> outer_loop:none
+
+ // There's a 3rd `if` due to bounds checks.
+ /// CHECK-START: void Main.peelingAddInts(int[]) dead_code_elimination$final (after)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK-NOT: If
private static final void peelingAddInts(int[] a) {
for (int i = 0; a != null && i < a.length; i++) {
a[i] += 1;
@@ -830,8 +1106,16 @@ public class Main {
/// CHECK-DAG: ArraySet loop:<<Loop1>> outer_loop:<<Loop0>>
/// CHECK-DAG: <<IndAdd1:i\d+>> Add [<<Phi1>>,<<Const1>>] loop:<<Loop1>> outer_loop:<<Loop0>>
/// CHECK-DAG: <<IndAdd0:i\d+>> Add [<<Phi0>>,<<Const1>>] loop:<<Loop0>> outer_loop:none
- //
+
+ // The two loops have an `if`. The 3rd `if` is the explicit one in the innermost loop.
+ /// CHECK-START: void Main.peelingBreakFromNest(int[], boolean) loop_optimization (before)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
/// CHECK-NOT: If
+
+ /// CHECK-START: void Main.peelingBreakFromNest(int[], boolean) loop_optimization (before)
+ /// CHECK: ArraySet
/// CHECK-NOT: ArraySet
/// CHECK-START: void Main.peelingBreakFromNest(int[], boolean) dead_code_elimination$final (after)
@@ -850,8 +1134,16 @@ public class Main {
/// CHECK-DAG: ArraySet loop:<<Loop1>> outer_loop:<<Loop0>>
/// CHECK-DAG: <<IndAdd1:i\d+>> Add [<<Phi1>>,<<Const1>>] loop:<<Loop1>> outer_loop:<<Loop0>>
/// CHECK-DAG: <<IndAdd0:i\d+>> Add [<<Phi0>>,<<Const1>>] loop:<<Loop0>> outer_loop:none
- //
+
+ /// CHECK-START: void Main.peelingBreakFromNest(int[], boolean) dead_code_elimination$final (after)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
/// CHECK-NOT: If
+
+ /// CHECK-START: void Main.peelingBreakFromNest(int[], boolean) dead_code_elimination$final (after)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
/// CHECK-NOT: ArraySet
private static final void peelingBreakFromNest(int[] a, boolean f) {
outer:
@@ -873,7 +1165,9 @@ public class Main {
/// CHECK-DAG: <<Phi:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none
/// CHECK-DAG: If [<<Check>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none
- //
+
+ /// CHECK-START: int Main.peelingHoistOneControl(int) loop_optimization (before)
+ /// CHECK: If
/// CHECK-NOT: If
/// CHECK-START: int Main.peelingHoistOneControl(int) dead_code_elimination$final (after)
@@ -886,8 +1180,15 @@ public class Main {
//
// Check that the loop has no instruction except SuspendCheck and Goto (indefinite loop).
/// CHECK-NOT: loop:<<Loop>> outer_loop:none
+
+ /// CHECK-START: int Main.peelingHoistOneControl(int) dead_code_elimination$final (after)
+ /// CHECK: If
/// CHECK-NOT: If
+
+ /// CHECK-START: int Main.peelingHoistOneControl(int) dead_code_elimination$final (after)
/// CHECK-NOT: Phi
+
+ /// CHECK-START: int Main.peelingHoistOneControl(int) dead_code_elimination$final (after)
/// CHECK-NOT: Add
private static final int peelingHoistOneControl(int x) {
int i = 0;
@@ -902,11 +1203,17 @@ public class Main {
/// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
/// CHECK-DAG: If loop:<<Loop>> outer_loop:none
/// CHECK-DAG: If loop:<<Loop>> outer_loop:none
- //
+
/// CHECK-START: int Main.peelingHoistOneControl(int, int) dead_code_elimination$final (after)
/// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
/// CHECK-DAG: If loop:<<Loop>> outer_loop:none
- /// CHECK-NOT: If loop:<<Loop>> outer_loop:none
+
+ // One `if` inside the loop (the one no longer invariant), two outside of it.
+ /// CHECK-START: int Main.peelingHoistOneControl(int, int) dead_code_elimination$final (after)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK-NOT: If
private static final int peelingHoistOneControl(int x, int y) {
while (true) {
if (x == 0)
@@ -922,11 +1229,18 @@ public class Main {
/// CHECK-DAG: If loop:<<Loop>> outer_loop:none
/// CHECK-DAG: If loop:<<Loop>> outer_loop:none
/// CHECK-DAG: If loop:<<Loop>> outer_loop:none
- //
+
/// CHECK-START: int Main.peelingHoistTwoControl(int, int, int) dead_code_elimination$final (after)
/// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
/// CHECK-DAG: If loop:<<Loop>> outer_loop:none
- /// CHECK-NOT: If loop:<<Loop>> outer_loop:none
+
+ // One `if` inside the loop (the one no longer invariant), three outside of it.
+ /// CHECK-START: int Main.peelingHoistTwoControl(int, int, int) dead_code_elimination$final (after)
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK: If
+ /// CHECK-NOT: If
private static final int peelingHoistTwoControl(int x, int y, int z) {
while (true) {
if (x == 0)
@@ -948,8 +1262,14 @@ public class Main {
/// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
- //
+
+ /// CHECK-START: void Main.unrollingFull(int[]) loop_optimization (before)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.unrollingFull(int[]) loop_optimization (before)
+ /// CHECK: ArraySet
/// CHECK-NOT: ArraySet
/// CHECK-START: void Main.unrollingFull(int[]) loop_optimization (after)
@@ -970,8 +1290,20 @@ public class Main {
/// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
/// CHECK-DAG: If [<<Const1>>] loop:<<Loop>> outer_loop:none
- //
+
+ /// CHECK-START: void Main.unrollingFull(int[]) loop_optimization (after)
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
+ /// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
+
+ /// CHECK-START: void Main.unrollingFull(int[]) loop_optimization (after)
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
+ /// CHECK: ArraySet
/// CHECK-NOT: ArraySet
private static final void unrollingFull(int[] a) {
for (int i = 0; i < 2; i++) {