Refactor handling of input records.
Introduce HInstruction::GetInputRecords(), a new virtual
function that returns an ArrayRef<> to all input records.
Implement all other functions dealing with input records as
wrappers around GetInputRecords(). Rewrite functions that
previously used multiple virtual calls to deal with input
records, especially in loops, to prefetch the ArrayRef<>
only once for each instruction. Besides avoiding all the
extra calls, this also allows the compiler (clang++) to
perform additional optimizations.
This speeds up the Nexus 5 boot image compilation by ~0.5s
(4% of "Compile Dex File", 2% of dex2oat time) on AOSP ToT.
Change-Id: Id8ebe0fb9405e38d918972a11bd724146e4ca578
diff --git a/compiler/optimizing/induction_var_analysis.cc b/compiler/optimizing/induction_var_analysis.cc
index c06d19d..0a5cf80 100644
--- a/compiler/optimizing/induction_var_analysis.cc
+++ b/compiler/optimizing/induction_var_analysis.cc
@@ -152,8 +152,8 @@
// Visit all descendants.
uint32_t low = d1;
- for (size_t i = 0, count = instruction->InputCount(); i < count; ++i) {
- low = std::min(low, VisitDescendant(loop, instruction->InputAt(i)));
+ for (HInstruction* input : instruction->GetInputs()) {
+ low = std::min(low, VisitDescendant(loop, input));
}
// Lower or found SCC?
@@ -341,11 +341,11 @@
HInstruction* phi,
size_t input_index) {
// Match all phi inputs from input_index onwards exactly.
- const size_t count = phi->InputCount();
- DCHECK_LT(input_index, count);
- InductionInfo* a = LookupInfo(loop, phi->InputAt(input_index));
- for (size_t i = input_index + 1; i < count; i++) {
- InductionInfo* b = LookupInfo(loop, phi->InputAt(i));
+ auto&& inputs = phi->GetInputs();
+ DCHECK_LT(input_index, inputs.size());
+ InductionInfo* a = LookupInfo(loop, inputs[input_index]);
+ for (size_t i = input_index + 1; i < inputs.size(); i++) {
+ InductionInfo* b = LookupInfo(loop, inputs[i]);
if (!InductionEqual(a, b)) {
return nullptr;
}
@@ -464,12 +464,12 @@
HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::SolvePhi(HInstruction* phi,
size_t input_index) {
// Match all phi inputs from input_index onwards exactly.
- const size_t count = phi->InputCount();
- DCHECK_LT(input_index, count);
- auto ita = cycle_.find(phi->InputAt(input_index));
+ auto&& inputs = phi->GetInputs();
+ DCHECK_LT(input_index, inputs.size());
+ auto ita = cycle_.find(inputs[input_index]);
if (ita != cycle_.end()) {
- for (size_t i = input_index + 1; i < count; i++) {
- auto itb = cycle_.find(phi->InputAt(i));
+ for (size_t i = input_index + 1; i < inputs.size(); i++) {
+ auto itb = cycle_.find(inputs[i]);
if (itb == cycle_.end() ||
!HInductionVarAnalysis::InductionEqual(ita->second, itb->second)) {
return nullptr;