diff options
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/induction_var_analysis.cc | 8 | ||||
-rw-r--r-- | compiler/optimizing/induction_var_analysis_test.cc | 31 | ||||
-rw-r--r-- | compiler/optimizing/induction_var_range.cc | 30 |
3 files changed, 42 insertions, 27 deletions
diff --git a/compiler/optimizing/induction_var_analysis.cc b/compiler/optimizing/induction_var_analysis.cc index 129c2a94b5..c501ccf80f 100644 --- a/compiler/optimizing/induction_var_analysis.cc +++ b/compiler/optimizing/induction_var_analysis.cc @@ -714,10 +714,12 @@ void HInductionVarAnalysis::VisitTripCount(HLoopInformation* loop, case kCondGE: op = kGE; break; default: LOG(FATAL) << "CONDITION UNREACHABLE"; } + // Associate trip count with control instruction, rather than the condition (even + // though it's its use) since former provides a convenient use-free placeholder. + HInstruction* control = loop->GetHeader()->GetLastInstruction(); InductionInfo* taken_test = CreateInvariantOp(op, lower_expr, upper_expr); - AssignInfo(loop, - loop->GetHeader()->GetLastInstruction(), - CreateTripCount(tcKind, trip_count, taken_test, type)); + DCHECK(control->IsIf()); + AssignInfo(loop, control, CreateTripCount(tcKind, trip_count, taken_test, type)); } bool HInductionVarAnalysis::IsTaken(InductionInfo* lower_expr, diff --git a/compiler/optimizing/induction_var_analysis_test.cc b/compiler/optimizing/induction_var_analysis_test.cc index 580d24b74b..292bc4e06e 100644 --- a/compiler/optimizing/induction_var_analysis_test.cc +++ b/compiler/optimizing/induction_var_analysis_test.cc @@ -157,6 +157,13 @@ class InductionVarAnalysisTest : public CommonCompilerTest { iva_->LookupInfo(loop_body_[d]->GetLoopInformation(), instruction)); } + // Returns induction information of the trip-count of loop at depth d. + std::string GetTripCount(int d) { + HInstruction* control = loop_header_[d]->GetLastInstruction(); + DCHECK(control->IsIf()); + return GetInductionInfo(control, d); + } + // Returns true if instructions have identical induction. bool HaveSameInduction(HInstruction* instruction1, HInstruction* instruction2) { return HInductionVarAnalysis::InductionEqual( @@ -239,8 +246,7 @@ TEST_F(InductionVarAnalysisTest, FindBasicInduction) { EXPECT_FALSE(HaveSameInduction(store->InputAt(1), increment_[0])); // Trip-count. - EXPECT_STREQ("((100) (TC-loop) ((0) < (100)))", - GetInductionInfo(loop_header_[0]->GetLastInstruction(), 0).c_str()); + EXPECT_STREQ("((100) (TC-loop) ((0) < (100)))", GetTripCount(0).c_str()); } TEST_F(InductionVarAnalysisTest, FindDerivedInduction) { @@ -579,8 +585,7 @@ TEST_F(InductionVarAnalysisTest, FindDeepLoopInduction) { } EXPECT_STREQ("((1) * i + (1)):PrimInt", GetInductionInfo(increment_[d], d).c_str()); // Trip-count. - EXPECT_STREQ("((100) (TC-loop) ((0) < (100)))", - GetInductionInfo(loop_header_[d]->GetLastInstruction(), d).c_str()); + EXPECT_STREQ("((100) (TC-loop) ((0) < (100)))", GetTripCount(d).c_str()); } } @@ -607,8 +612,7 @@ TEST_F(InductionVarAnalysisTest, ByteInductionIntLoopControl) { EXPECT_FALSE(HaveSameInduction(store1->InputAt(1), store2->InputAt(1))); // Trip-count. - EXPECT_STREQ("((100) (TC-loop) ((0) < (100)))", - GetInductionInfo(loop_header_[0]->GetLastInstruction(), 0).c_str()); + EXPECT_STREQ("((100) (TC-loop) ((0) < (100)))", GetTripCount(0).c_str()); } TEST_F(InductionVarAnalysisTest, ByteLoopControl1) { @@ -626,8 +630,7 @@ TEST_F(InductionVarAnalysisTest, ByteLoopControl1) { EXPECT_STREQ("((1) * i + ((-128) + (1))):PrimByte", GetInductionInfo(increment_[0], 0).c_str()); // Trip-count. - EXPECT_STREQ("(((127) - (-128)) (TC-loop) ((-128) < (127)))", - GetInductionInfo(loop_header_[0]->GetLastInstruction(), 0).c_str()); + EXPECT_STREQ("(((127) - (-128)) (TC-loop) ((-128) < (127)))", GetTripCount(0).c_str()); } TEST_F(InductionVarAnalysisTest, ByteLoopControl2) { @@ -645,7 +648,7 @@ TEST_F(InductionVarAnalysisTest, ByteLoopControl2) { EXPECT_STREQ("((1) * i + ((-128) + (1))):PrimByte", GetInductionInfo(increment_[0], 0).c_str()); // Trip-count undefined. - EXPECT_STREQ("", GetInductionInfo(loop_header_[0]->GetLastInstruction(), 0).c_str()); + EXPECT_STREQ("", GetTripCount(0).c_str()); } TEST_F(InductionVarAnalysisTest, ShortLoopControl1) { @@ -664,8 +667,7 @@ TEST_F(InductionVarAnalysisTest, ShortLoopControl1) { EXPECT_STREQ("((1) * i + ((-32768) + (1))):PrimShort", GetInductionInfo(increment_[0], 0).c_str()); // Trip-count. - EXPECT_STREQ("(((32767) - (-32768)) (TC-loop) ((-32768) < (32767)))", - GetInductionInfo(loop_header_[0]->GetLastInstruction(), 0).c_str()); + EXPECT_STREQ("(((32767) - (-32768)) (TC-loop) ((-32768) < (32767)))", GetTripCount(0).c_str()); } TEST_F(InductionVarAnalysisTest, ShortLoopControl2) { @@ -684,7 +686,7 @@ TEST_F(InductionVarAnalysisTest, ShortLoopControl2) { EXPECT_STREQ("((1) * i + ((-32768) + (1))):PrimShort", GetInductionInfo(increment_[0], 0).c_str()); // Trip-count undefined. - EXPECT_STREQ("", GetInductionInfo(loop_header_[0]->GetLastInstruction(), 0).c_str()); + EXPECT_STREQ("", GetTripCount(0).c_str()); } TEST_F(InductionVarAnalysisTest, CharLoopControl1) { @@ -701,8 +703,7 @@ TEST_F(InductionVarAnalysisTest, CharLoopControl1) { EXPECT_STREQ("((1) * i + (1)):PrimChar", GetInductionInfo(increment_[0], 0).c_str()); // Trip-count. - EXPECT_STREQ("((65535) (TC-loop) ((0) < (65535)))", - GetInductionInfo(loop_header_[0]->GetLastInstruction(), 0).c_str()); + EXPECT_STREQ("((65535) (TC-loop) ((0) < (65535)))", GetTripCount(0).c_str()); } TEST_F(InductionVarAnalysisTest, CharLoopControl2) { @@ -719,7 +720,7 @@ TEST_F(InductionVarAnalysisTest, CharLoopControl2) { EXPECT_STREQ("((1) * i + (1)):PrimChar", GetInductionInfo(increment_[0], 0).c_str()); // Trip-count undefined. - EXPECT_STREQ("", GetInductionInfo(loop_header_[0]->GetLastInstruction(), 0).c_str()); + EXPECT_STREQ("", GetTripCount(0).c_str()); } } // namespace art diff --git a/compiler/optimizing/induction_var_range.cc b/compiler/optimizing/induction_var_range.cc index 18e6f5ca9f..cd8b7c7960 100644 --- a/compiler/optimizing/induction_var_range.cc +++ b/compiler/optimizing/induction_var_range.cc @@ -106,6 +106,12 @@ static HInstruction* Insert(HBasicBlock* block, HInstruction* instruction) { return instruction; } +/** Helper method to obtain loop's control instruction. */ +static HInstruction* GetLoopControl(HLoopInformation* loop) { + DCHECK(loop != nullptr); + return loop->GetHeader()->GetLastInstruction(); +} + // // Public class methods. // @@ -179,7 +185,7 @@ void InductionVarRange::GenerateRange(HInstruction* context, /*out*/HInstruction** lower, /*out*/HInstruction** upper) { bool is_last_value = false; - int64_t s = 0; + int64_t stride_value = 0; bool b1, b2; // unused if (!GenerateCode(context, instruction, @@ -189,7 +195,7 @@ void InductionVarRange::GenerateRange(HInstruction* context, lower, upper, nullptr, - &s, + &stride_value, &b1, &b2)) { LOG(FATAL) << "Failed precondition: CanGenerateRange()"; @@ -232,7 +238,9 @@ bool InductionVarRange::CanGenerateLastValue(HInstruction* instruction) { nullptr, nullptr, nullptr, // nothing generated yet - &stride_value, &needs_finite_test, &needs_taken_test) + &stride_value, + &needs_finite_test, + &needs_taken_test) && !needs_finite_test && !needs_taken_test; } @@ -265,7 +273,10 @@ void InductionVarRange::Replace(HInstruction* instruction, for (HLoopInformation* lp = instruction->GetBlock()->GetLoopInformation(); // closest enveloping loop lp != nullptr; lp = lp->GetPreHeader()->GetLoopInformation()) { + // Update instruction's information. ReplaceInduction(induction_analysis_->LookupInfo(lp, instruction), fetch, replacement); + // Update loop's trip-count information. + ReplaceInduction(induction_analysis_->LookupInfo(lp, GetLoopControl(lp)), fetch, replacement); } } @@ -308,13 +319,13 @@ bool InductionVarRange::HasInductionInfo( /*out*/ HLoopInformation** loop, /*out*/ HInductionVarAnalysis::InductionInfo** info, /*out*/ HInductionVarAnalysis::InductionInfo** trip) const { - HLoopInformation* l = context->GetBlock()->GetLoopInformation(); // closest enveloping loop - if (l != nullptr) { - HInductionVarAnalysis::InductionInfo* i = induction_analysis_->LookupInfo(l, instruction); + HLoopInformation* lp = context->GetBlock()->GetLoopInformation(); // closest enveloping loop + if (lp != nullptr) { + HInductionVarAnalysis::InductionInfo* i = induction_analysis_->LookupInfo(lp, instruction); if (i != nullptr) { - *loop = l; + *loop = lp; *info = i; - *trip = induction_analysis_->LookupInfo(l, l->GetHeader()->GetLastInstruction()); + *trip = induction_analysis_->LookupInfo(lp, GetLoopControl(lp)); return true; } } @@ -878,7 +889,8 @@ bool InductionVarRange::GenerateCode(HInductionVarAnalysis::InductionInfo* info, } else if (stride_value == -1) { oper = new (graph->GetArena()) HSub(type, opb, opa); } else { - HInstruction* mul = new (graph->GetArena()) HMul(type, graph->GetIntConstant(stride_value), opa); + HInstruction* mul = new (graph->GetArena()) HMul( + type, graph->GetIntConstant(stride_value), opa); oper = new (graph->GetArena()) HAdd(type, Insert(block, mul), opb); } *result = Insert(block, oper); |