diff options
author | 2015-09-23 17:50:50 -0700 | |
---|---|---|
committer | 2015-09-23 18:36:11 -0700 | |
commit | cd26feb7e9f9eb36af9453f3cdb55cfc4e6e5ec4 (patch) | |
tree | 39768556d365d9830119f03aae81de1e7ee3efd3 /compiler/optimizing | |
parent | a6cfe5a3acb3af782322fde734bfcf0c524d6f99 (diff) |
Minor cleanup in range analysis.
(1) replaced min/max macro as previously required.
(2) removed some redundant code by merging min/max into one.
Change-Id: I610879a06d550346bfac7e6e12ec0299ba226a37
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/induction_var_analysis.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/induction_var_range.cc | 118 | ||||
-rw-r--r-- | compiler/optimizing/induction_var_range.h | 10 | ||||
-rw-r--r-- | compiler/optimizing/induction_var_range_test.cc | 20 |
4 files changed, 58 insertions, 94 deletions
diff --git a/compiler/optimizing/induction_var_analysis.cc b/compiler/optimizing/induction_var_analysis.cc index 1ff6bbeccf..9fb4304450 100644 --- a/compiler/optimizing/induction_var_analysis.cc +++ b/compiler/optimizing/induction_var_analysis.cc @@ -557,8 +557,8 @@ void HInductionVarAnalysis::VisitCondition(HLoopInformation* loop, InductionInfo* lo_val = a->op_b; InductionInfo* hi_val = b; // Analyze stride (may be compound). - InductionVarRange::Value v1 = InductionVarRange::GetMin(stride, nullptr); - InductionVarRange::Value v2 = InductionVarRange::GetMax(stride, nullptr); + InductionVarRange::Value v1 = InductionVarRange::GetVal(stride, nullptr, /* is_min */ true); + InductionVarRange::Value v2 = InductionVarRange::GetVal(stride, nullptr, /* is_min */ false); if (v1.a_constant != 0 || v2.a_constant != 0 || v1.b_constant != v2.b_constant) { return; } diff --git a/compiler/optimizing/induction_var_range.cc b/compiler/optimizing/induction_var_range.cc index 311042756f..119a80b6f4 100644 --- a/compiler/optimizing/induction_var_range.cc +++ b/compiler/optimizing/induction_var_range.cc @@ -14,15 +14,15 @@ * limitations under the License. */ -#include <limits.h> - #include "induction_var_range.h" +#include <limits> + namespace art { /** Returns true if 64-bit constant fits in 32-bit constant. */ static bool CanLongValueFitIntoInt(int64_t c) { - return INT_MIN <= c && c <= INT_MAX; + return std::numeric_limits<int32_t>::min() <= c && c <= std::numeric_limits<int32_t>::max(); } /** Returns true if 32-bit addition can be done safely. */ @@ -88,7 +88,8 @@ InductionVarRange::Value InductionVarRange::GetMinInduction(HInstruction* contex HInstruction* instruction) { HLoopInformation* loop = context->GetBlock()->GetLoopInformation(); if (loop != nullptr) { - return GetMin(induction_analysis_->LookupInfo(loop, instruction), GetTripCount(loop, context)); + return GetVal(induction_analysis_->LookupInfo(loop, instruction), + GetTripCount(loop, context), /* is_min */ true); } return Value(); } @@ -98,7 +99,8 @@ InductionVarRange::Value InductionVarRange::GetMaxInduction(HInstruction* contex HLoopInformation* loop = context->GetBlock()->GetLoopInformation(); if (loop != nullptr) { return SimplifyMax( - GetMax(induction_analysis_->LookupInfo(loop, instruction), GetTripCount(loop, context))); + GetVal(induction_analysis_->LookupInfo(loop, instruction), + GetTripCount(loop, context), /* is_min */ false)); } return Value(); } @@ -150,73 +152,44 @@ InductionVarRange::Value InductionVarRange::GetFetch(HInstruction* instruction, return Value(instruction, 1, 0); } -InductionVarRange::Value InductionVarRange::GetMin(HInductionVarAnalysis::InductionInfo* info, - HInductionVarAnalysis::InductionInfo* trip) { - if (info != nullptr) { - switch (info->induction_class) { - case HInductionVarAnalysis::kInvariant: - // Invariants. - switch (info->operation) { - case HInductionVarAnalysis::kNop: // normalized: 0 - DCHECK_EQ(info->op_a, info->op_b); - return Value(0); - case HInductionVarAnalysis::kAdd: - return AddValue(GetMin(info->op_a, trip), GetMin(info->op_b, trip)); - case HInductionVarAnalysis::kSub: // second max! - return SubValue(GetMin(info->op_a, trip), GetMax(info->op_b, trip)); - case HInductionVarAnalysis::kNeg: // second max! - return SubValue(Value(0), GetMax(info->op_b, trip)); - case HInductionVarAnalysis::kMul: - return GetMul(info->op_a, info->op_b, trip, true); - case HInductionVarAnalysis::kDiv: - return GetDiv(info->op_a, info->op_b, trip, true); - case HInductionVarAnalysis::kFetch: - return GetFetch(info->fetch, trip, true); - } - break; - case HInductionVarAnalysis::kLinear: - // Minimum over linear induction a * i + b, for normalized 0 <= i < TC. - return AddValue(GetMul(info->op_a, trip, trip, true), GetMin(info->op_b, trip)); - case HInductionVarAnalysis::kWrapAround: - case HInductionVarAnalysis::kPeriodic: - // Minimum over all values in the wrap-around/periodic. - return MinValue(GetMin(info->op_a, trip), GetMin(info->op_b, trip)); - } - } - return Value(); -} - -InductionVarRange::Value InductionVarRange::GetMax(HInductionVarAnalysis::InductionInfo* info, - HInductionVarAnalysis::InductionInfo* trip) { +InductionVarRange::Value InductionVarRange::GetVal(HInductionVarAnalysis::InductionInfo* info, + HInductionVarAnalysis::InductionInfo* trip, + bool is_min) { if (info != nullptr) { switch (info->induction_class) { case HInductionVarAnalysis::kInvariant: // Invariants. switch (info->operation) { - case HInductionVarAnalysis::kNop: // normalized: TC - 1 + case HInductionVarAnalysis::kNop: // normalized: 0 or TC-1 DCHECK_EQ(info->op_a, info->op_b); - return SubValue(GetMax(info->op_b, trip), Value(1)); + return is_min ? Value(0) + : SubValue(GetVal(info->op_b, trip, is_min), Value(1)); case HInductionVarAnalysis::kAdd: - return AddValue(GetMax(info->op_a, trip), GetMax(info->op_b, trip)); - case HInductionVarAnalysis::kSub: // second min! - return SubValue(GetMax(info->op_a, trip), GetMin(info->op_b, trip)); - case HInductionVarAnalysis::kNeg: // second min! - return SubValue(Value(0), GetMin(info->op_b, trip)); + return AddValue(GetVal(info->op_a, trip, is_min), + GetVal(info->op_b, trip, is_min)); + case HInductionVarAnalysis::kSub: // second reversed! + return SubValue(GetVal(info->op_a, trip, is_min), + GetVal(info->op_b, trip, !is_min)); + case HInductionVarAnalysis::kNeg: // second reversed! + return SubValue(Value(0), + GetVal(info->op_b, trip, !is_min)); case HInductionVarAnalysis::kMul: - return GetMul(info->op_a, info->op_b, trip, false); + return GetMul(info->op_a, info->op_b, trip, is_min); case HInductionVarAnalysis::kDiv: - return GetDiv(info->op_a, info->op_b, trip, false); + return GetDiv(info->op_a, info->op_b, trip, is_min); case HInductionVarAnalysis::kFetch: - return GetFetch(info->fetch, trip, false); + return GetFetch(info->fetch, trip, is_min); } break; case HInductionVarAnalysis::kLinear: - // Maximum over linear induction a * i + b, for normalized 0 <= i < TC. - return AddValue(GetMul(info->op_a, trip, trip, false), GetMax(info->op_b, trip)); + // Linear induction a * i + b, for normalized 0 <= i < TC. + return AddValue(GetMul(info->op_a, trip, trip, is_min), + GetVal(info->op_b, trip, is_min)); case HInductionVarAnalysis::kWrapAround: case HInductionVarAnalysis::kPeriodic: - // Maximum over all values in the wrap-around/periodic. - return MaxValue(GetMax(info->op_a, trip), GetMax(info->op_b, trip)); + // Merge values in the wrap-around/periodic. + return MergeVal(GetVal(info->op_a, trip, is_min), + GetVal(info->op_b, trip, is_min), is_min); } } return Value(); @@ -226,10 +199,10 @@ InductionVarRange::Value InductionVarRange::GetMul(HInductionVarAnalysis::Induct HInductionVarAnalysis::InductionInfo* info2, HInductionVarAnalysis::InductionInfo* trip, bool is_min) { - Value v1_min = GetMin(info1, trip); - Value v1_max = GetMax(info1, trip); - Value v2_min = GetMin(info2, trip); - Value v2_max = GetMax(info2, trip); + Value v1_min = GetVal(info1, trip, /* is_min */ true); + Value v1_max = GetVal(info1, trip, /* is_min */ false); + Value v2_min = GetVal(info2, trip, /* is_min */ true); + Value v2_max = GetVal(info2, trip, /* is_min */ false); if (v1_min.is_known && v1_min.a_constant == 0 && v1_min.b_constant >= 0) { // Positive range vs. positive or negative range. if (v2_min.is_known && v2_min.a_constant == 0 && v2_min.b_constant >= 0) { @@ -256,10 +229,10 @@ InductionVarRange::Value InductionVarRange::GetDiv(HInductionVarAnalysis::Induct HInductionVarAnalysis::InductionInfo* info2, HInductionVarAnalysis::InductionInfo* trip, bool is_min) { - Value v1_min = GetMin(info1, trip); - Value v1_max = GetMax(info1, trip); - Value v2_min = GetMin(info2, trip); - Value v2_max = GetMax(info2, trip); + Value v1_min = GetVal(info1, trip, /* is_min */ true); + Value v1_max = GetVal(info1, trip, /* is_min */ false); + Value v2_min = GetVal(info2, trip, /* is_min */ true); + Value v2_max = GetVal(info2, trip, /* is_min */ false); if (v1_min.is_known && v1_min.a_constant == 0 && v1_min.b_constant >= 0) { // Positive range vs. positive or negative range. if (v2_min.is_known && v2_min.a_constant == 0 && v2_min.b_constant >= 0) { @@ -334,19 +307,12 @@ InductionVarRange::Value InductionVarRange::DivValue(Value v1, Value v2) { return Value(); } -InductionVarRange::Value InductionVarRange::MinValue(Value v1, Value v2) { - if (v1.is_known && v2.is_known) { - if (v1.instruction == v2.instruction && v1.a_constant == v2.a_constant) { - return Value(v1.instruction, v1.a_constant, std::min(v1.b_constant, v2.b_constant)); - } - } - return Value(); -} - -InductionVarRange::Value InductionVarRange::MaxValue(Value v1, Value v2) { +InductionVarRange::Value InductionVarRange::MergeVal(Value v1, Value v2, bool is_min) { if (v1.is_known && v2.is_known) { if (v1.instruction == v2.instruction && v1.a_constant == v2.a_constant) { - return Value(v1.instruction, v1.a_constant, std::max(v1.b_constant, v2.b_constant)); + return Value(v1.instruction, v1.a_constant, + is_min ? std::min(v1.b_constant, v2.b_constant) + : std::max(v1.b_constant, v2.b_constant)); } } return Value(); diff --git a/compiler/optimizing/induction_var_range.h b/compiler/optimizing/induction_var_range.h index 96cbd46279..8280c8bedc 100644 --- a/compiler/optimizing/induction_var_range.h +++ b/compiler/optimizing/induction_var_range.h @@ -79,10 +79,9 @@ class InductionVarRange { HInductionVarAnalysis::InductionInfo* trip, bool is_min); - static Value GetMin(HInductionVarAnalysis::InductionInfo* info, - HInductionVarAnalysis::InductionInfo* trip); - static Value GetMax(HInductionVarAnalysis::InductionInfo* info, - HInductionVarAnalysis::InductionInfo* trip); + static Value GetVal(HInductionVarAnalysis::InductionInfo* info, + HInductionVarAnalysis::InductionInfo* trip, + bool is_min); static Value GetMul(HInductionVarAnalysis::InductionInfo* info1, HInductionVarAnalysis::InductionInfo* info2, HInductionVarAnalysis::InductionInfo* trip, @@ -96,8 +95,7 @@ class InductionVarRange { static Value SubValue(Value v1, Value v2); static Value MulValue(Value v1, Value v2); static Value DivValue(Value v1, Value v2); - static Value MinValue(Value v1, Value v2); - static Value MaxValue(Value v1, Value v2); + static Value MergeVal(Value v1, Value v2, bool is_min); /** Results of prior induction variable analysis. */ HInductionVarAnalysis *induction_analysis_; diff --git a/compiler/optimizing/induction_var_range_test.cc b/compiler/optimizing/induction_var_range_test.cc index c8abe36119..5d9a075aef 100644 --- a/compiler/optimizing/induction_var_range_test.cc +++ b/compiler/optimizing/induction_var_range_test.cc @@ -14,8 +14,6 @@ * limitations under the License. */ -#include <limits.h> - #include "base/arena_allocator.h" #include "builder.h" #include "gtest/gtest.h" @@ -114,12 +112,12 @@ class InductionVarRangeTest : public testing::Test { Value GetMin(HInductionVarAnalysis::InductionInfo* info, HInductionVarAnalysis::InductionInfo* induc) { - return InductionVarRange::GetMin(info, induc); + return InductionVarRange::GetVal(info, induc, /* is_min */ true); } Value GetMax(HInductionVarAnalysis::InductionInfo* info, HInductionVarAnalysis::InductionInfo* induc) { - return InductionVarRange::GetMax(info, induc); + return InductionVarRange::GetVal(info, induc, /* is_min */ false); } Value GetMul(HInductionVarAnalysis::InductionInfo* info1, @@ -138,8 +136,8 @@ class InductionVarRangeTest : public testing::Test { Value SubValue(Value v1, Value v2) { return InductionVarRange::SubValue(v1, v2); } Value MulValue(Value v1, Value v2) { return InductionVarRange::MulValue(v1, v2); } Value DivValue(Value v1, Value v2) { return InductionVarRange::DivValue(v1, v2); } - Value MinValue(Value v1, Value v2) { return InductionVarRange::MinValue(v1, v2); } - Value MaxValue(Value v1, Value v2) { return InductionVarRange::MaxValue(v1, v2); } + Value MinValue(Value v1, Value v2) { return InductionVarRange::MergeVal(v1, v2, true); } + Value MaxValue(Value v1, Value v2) { return InductionVarRange::MergeVal(v1, v2, false); } // General building fields. ArenaPool pool_; @@ -288,8 +286,9 @@ TEST_F(InductionVarRangeTest, AddValue) { ExpectEqual(Value(), AddValue(Value(&x_, 1, 5), Value(&y_, 1, -7))); ExpectEqual(Value(&x_, 1, 23), AddValue(Value(&x_, 1, 20), Value(3))); ExpectEqual(Value(&y_, 1, 5), AddValue(Value(55), Value(&y_, 1, -50))); - ExpectEqual(Value(INT_MAX), AddValue(Value(INT_MAX - 5), Value(5))); - ExpectEqual(Value(), AddValue(Value(INT_MAX - 5), Value(6))); // unsafe + const int32_t max_value = std::numeric_limits<int32_t>::max(); + ExpectEqual(Value(max_value), AddValue(Value(max_value - 5), Value(5))); + ExpectEqual(Value(), AddValue(Value(max_value - 5), Value(6))); // unsafe } TEST_F(InductionVarRangeTest, SubValue) { @@ -299,8 +298,9 @@ TEST_F(InductionVarRangeTest, SubValue) { ExpectEqual(Value(), SubValue(Value(&x_, 1, 5), Value(&y_, 1, -7))); ExpectEqual(Value(&x_, 1, 17), SubValue(Value(&x_, 1, 20), Value(3))); ExpectEqual(Value(&y_, -4, 105), SubValue(Value(55), Value(&y_, 4, -50))); - ExpectEqual(Value(INT_MIN), SubValue(Value(INT_MIN + 5), Value(5))); - ExpectEqual(Value(), SubValue(Value(INT_MIN + 5), Value(6))); // unsafe + const int32_t min_value = std::numeric_limits<int32_t>::min(); + ExpectEqual(Value(min_value), SubValue(Value(min_value + 5), Value(5))); + ExpectEqual(Value(), SubValue(Value(min_value + 5), Value(6))); // unsafe } TEST_F(InductionVarRangeTest, MulValue) { |