diff options
author | 2016-10-18 13:03:31 -0700 | |
---|---|---|
committer | 2016-10-20 14:14:17 -0700 | |
commit | 639cc8c7bbb7d8c341173bcf24604ccb4328acb8 (patch) | |
tree | ae8181b94ddd145edaff141a2b351478161f1559 /compiler/optimizing/induction_var_analysis.cc | |
parent | 3941c882ea7b54772dec36a9a1b33e0b8a7474f7 (diff) |
Improve recognition of select-based period induction.
Rationale:
Similar to the previous CL, this helps to eliminate more dead induction.
Now, CaffeineLogic, when compiled with dx (rather than jack) improves
by a 1.5 speedup (9000us -> 6000us).
Note:
We need to run the simplifier before induction analysis to trigger
the select simplification first. Although a bit of a compile-time hit,
it seems a good idea to run a simplifier here again anyway.
Test: test-art-host
Change-Id: I93b91ca40a4d64385c64393028e8d213f0c904a8
Diffstat (limited to 'compiler/optimizing/induction_var_analysis.cc')
-rw-r--r-- | compiler/optimizing/induction_var_analysis.cc | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/compiler/optimizing/induction_var_analysis.cc b/compiler/optimizing/induction_var_analysis.cc index 55fcb12fa8..38937bf488 100644 --- a/compiler/optimizing/induction_var_analysis.cc +++ b/compiler/optimizing/induction_var_analysis.cc @@ -286,8 +286,11 @@ void HInductionVarAnalysis::ClassifyNonTrivial(HLoopInformation* loop) { update = SolveAddSub( loop, phi, instruction, instruction->InputAt(0), instruction->InputAt(1), kSub, true); } else if (instruction->IsXor()) { - update = SolveXor( - loop, phi, instruction, instruction->InputAt(0), instruction->InputAt(1), true); + update = SolveXor(loop, phi, instruction, instruction->InputAt(0), instruction->InputAt(1)); + } else if (instruction->IsEqual()) { + update = SolveTest(loop, phi, instruction, 0); + } else if (instruction->IsNotEqual()) { + update = SolveTest(loop, phi, instruction, 1); } else if (instruction->IsTypeConversion()) { update = SolveCnv(instruction->AsTypeConversion()); } @@ -560,19 +563,34 @@ HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::SolveXor(HLoopInfor HInstruction* entry_phi, HInstruction* instruction, HInstruction* x, - HInstruction* y, - bool is_first_call) { - InductionInfo* b = LookupInfo(loop, y); - // Solve within a tight cycle on x = x ^ c. - if (b != nullptr && b->induction_class == kInvariant) { - if (x == entry_phi && entry_phi->InputCount() == 2 && instruction == entry_phi->InputAt(1)) { - InductionInfo* initial = LookupInfo(loop, entry_phi->InputAt(0)); + HInstruction* y) { + // Solve within a tight cycle on x = c ^ x or x = x ^ c. + if (entry_phi->InputCount() == 2 && instruction == entry_phi->InputAt(1)) { + InductionInfo* initial = LookupInfo(loop, entry_phi->InputAt(0)); + InductionInfo* a = LookupInfo(loop, x); + if (a != nullptr && a->induction_class == kInvariant && entry_phi == y) { + return CreateInduction(kPeriodic, CreateInvariantOp(kXor, a, initial), initial, type_); + } + InductionInfo* b = LookupInfo(loop, y); + if (b != nullptr && b->induction_class == kInvariant && entry_phi == x) { return CreateInduction(kPeriodic, CreateInvariantOp(kXor, initial, b), initial, type_); } } - // Try the other way around if considered for first time. - if (is_first_call) { - return SolveXor(loop, entry_phi, instruction, y, x, false); + return nullptr; +} + +HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::SolveTest(HLoopInformation* loop, + HInstruction* entry_phi, + HInstruction* instruction, + int64_t opposite_value) { + // Detect hidden XOR construction in tight cycles on x = (x == 0) or x = (x != 1). + int64_t value = -1; + HInstruction* x = instruction->InputAt(0); + HInstruction* y = instruction->InputAt(1); + if (IsExact(LookupInfo(loop, x), &value) && value == opposite_value) { + return SolveXor(loop, entry_phi, instruction, graph_->GetIntConstant(1), y); + } else if (IsExact(LookupInfo(loop, y), &value) && value == opposite_value) { + return SolveXor(loop, entry_phi, instruction, x, graph_->GetIntConstant(1)); } return nullptr; } |