diff options
Diffstat (limited to 'compiler/optimizing')
| -rw-r--r-- | compiler/optimizing/bounds_check_elimination.cc | 19 | ||||
| -rw-r--r-- | compiler/optimizing/bounds_check_elimination_test.cc | 8 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 11 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_arm64.cc | 14 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_arm_vixl.cc | 7 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_mips.cc | 15 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_mips64.cc | 13 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 11 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 13 | ||||
| -rw-r--r-- | compiler/optimizing/induction_var_range.cc | 9 | ||||
| -rw-r--r-- | compiler/optimizing/induction_var_range_test.cc | 9 | ||||
| -rw-r--r-- | compiler/optimizing/inliner.cc | 9 | ||||
| -rw-r--r-- | compiler/optimizing/instruction_builder.cc | 24 | ||||
| -rw-r--r-- | compiler/optimizing/instruction_simplifier.cc | 4 | ||||
| -rw-r--r-- | compiler/optimizing/nodes.h | 63 | ||||
| -rw-r--r-- | compiler/optimizing/reference_type_propagation.cc | 6 |
16 files changed, 148 insertions, 87 deletions
diff --git a/compiler/optimizing/bounds_check_elimination.cc b/compiler/optimizing/bounds_check_elimination.cc index 2ee4db923a..7dc094b25f 100644 --- a/compiler/optimizing/bounds_check_elimination.cc +++ b/compiler/optimizing/bounds_check_elimination.cc @@ -153,6 +153,21 @@ class ValueBound : public ValueObject { return instruction_ == bound.instruction_ && constant_ == bound.constant_; } + /* + * Hunt "under the hood" of array lengths (leading to array references), + * null checks (also leading to array references), and new arrays + * (leading to the actual length). This makes it more likely related + * instructions become actually comparable. + */ + static HInstruction* HuntForDeclaration(HInstruction* instruction) { + while (instruction->IsArrayLength() || + instruction->IsNullCheck() || + instruction->IsNewArray()) { + instruction = instruction->InputAt(0); + } + return instruction; + } + static bool Equal(HInstruction* instruction1, HInstruction* instruction2) { if (instruction1 == instruction2) { return true; @@ -1121,7 +1136,7 @@ class BCEVisitor : public HGraphVisitor { } void VisitNewArray(HNewArray* new_array) OVERRIDE { - HInstruction* len = new_array->GetLength(); + HInstruction* len = new_array->InputAt(0); if (!len->IsIntConstant()) { HInstruction *left; int32_t right_const; @@ -1309,7 +1324,7 @@ class BCEVisitor : public HGraphVisitor { InductionVarRange::Value v2; bool needs_finite_test = false; HInstruction* index = context->InputAt(0); - HInstruction* hint = HuntForDeclaration(context->InputAt(1)); + HInstruction* hint = ValueBound::HuntForDeclaration(context->InputAt(1)); if (induction_range_.GetInductionRange(context, index, hint, &v1, &v2, &needs_finite_test)) { if (v1.is_known && (v1.a_constant == 0 || v1.a_constant == 1) && v2.is_known && (v2.a_constant == 0 || v2.a_constant == 1)) { diff --git a/compiler/optimizing/bounds_check_elimination_test.cc b/compiler/optimizing/bounds_check_elimination_test.cc index 5d58207511..dfa150406d 100644 --- a/compiler/optimizing/bounds_check_elimination_test.cc +++ b/compiler/optimizing/bounds_check_elimination_test.cc @@ -596,11 +596,13 @@ static HInstruction* BuildSSAGraph3(HGraph* graph, HBasicBlock* block = new (allocator) HBasicBlock(graph); graph->AddBlock(block); entry->AddSuccessor(block); - // We pass a bogus constant for the class to avoid mocking one. HInstruction* new_array = new (allocator) HNewArray( constant_10, - constant_10, - 0); + graph->GetCurrentMethod(), + 0, + dex::TypeIndex(static_cast<uint16_t>(Primitive::kPrimInt)), + graph->GetDexFile(), + kQuickAllocArray); block->AddInstruction(new_array); block->AddInstruction(new (allocator) HGoto()); diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index 9c9c604dca..07b174698a 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -3984,16 +3984,19 @@ void LocationsBuilderARM::VisitNewArray(HNewArray* instruction) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kCallOnMainOnly); InvokeRuntimeCallingConvention calling_convention; + locations->AddTemp(Location::RegisterLocation(calling_convention.GetRegisterAt(0))); locations->SetOut(Location::RegisterLocation(R0)); - locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0))); - locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(1))); + locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(1))); + locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(2))); } void InstructionCodeGeneratorARM::VisitNewArray(HNewArray* instruction) { + InvokeRuntimeCallingConvention calling_convention; + __ LoadImmediate(calling_convention.GetRegisterAt(0), instruction->GetTypeIndex().index_); // Note: if heap poisoning is enabled, the entry point takes cares // of poisoning the reference. - codegen_->InvokeRuntime(kQuickAllocArrayResolved, instruction, instruction->GetDexPc()); - CheckEntrypointTypes<kQuickAllocArrayResolved, void*, mirror::Class*, int32_t>(); + codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); + CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck, void*, uint32_t, int32_t, ArtMethod*>(); } void LocationsBuilderARM::VisitParameterValue(HParameterValue* instruction) { diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index 68d0b869e7..b094e54f8a 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -4747,16 +4747,22 @@ void LocationsBuilderARM64::VisitNewArray(HNewArray* instruction) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kCallOnMainOnly); InvokeRuntimeCallingConvention calling_convention; + locations->AddTemp(LocationFrom(calling_convention.GetRegisterAt(0))); locations->SetOut(LocationFrom(x0)); - locations->SetInAt(0, LocationFrom(calling_convention.GetRegisterAt(0))); - locations->SetInAt(1, LocationFrom(calling_convention.GetRegisterAt(1))); + locations->SetInAt(0, LocationFrom(calling_convention.GetRegisterAt(1))); + locations->SetInAt(1, LocationFrom(calling_convention.GetRegisterAt(2))); } void InstructionCodeGeneratorARM64::VisitNewArray(HNewArray* instruction) { + LocationSummary* locations = instruction->GetLocations(); + InvokeRuntimeCallingConvention calling_convention; + Register type_index = RegisterFrom(locations->GetTemp(0), Primitive::kPrimInt); + DCHECK(type_index.Is(w0)); + __ Mov(type_index, instruction->GetTypeIndex().index_); // Note: if heap poisoning is enabled, the entry point takes cares // of poisoning the reference. - codegen_->InvokeRuntime(kQuickAllocArrayResolved, instruction, instruction->GetDexPc()); - CheckEntrypointTypes<kQuickAllocArrayResolved, void*, mirror::Class*, int32_t>(); + codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); + CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck, void*, uint32_t, int32_t, ArtMethod*>(); } void LocationsBuilderARM64::VisitNewInstance(HNewInstance* instruction) { diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index 86304a192d..05a76e1105 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -3995,16 +3995,19 @@ void LocationsBuilderARMVIXL::VisitNewArray(HNewArray* instruction) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kCallOnMainOnly); InvokeRuntimeCallingConventionARMVIXL calling_convention; + locations->AddTemp(LocationFrom(calling_convention.GetRegisterAt(0))); locations->SetOut(LocationFrom(r0)); locations->SetInAt(0, LocationFrom(calling_convention.GetRegisterAt(1))); locations->SetInAt(1, LocationFrom(calling_convention.GetRegisterAt(2))); } void InstructionCodeGeneratorARMVIXL::VisitNewArray(HNewArray* instruction) { + InvokeRuntimeCallingConventionARMVIXL calling_convention; + __ Mov(calling_convention.GetRegisterAt(0), instruction->GetTypeIndex().index_); // Note: if heap poisoning is enabled, the entry point takes cares // of poisoning the reference. - codegen_->InvokeRuntime(kQuickAllocArrayResolved, instruction, instruction->GetDexPc()); - CheckEntrypointTypes<kQuickAllocArrayResolved, void*, mirror::Class*, int32_t>(); + codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); + CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck, void*, uint32_t, int32_t, ArtMethod*>(); } void LocationsBuilderARMVIXL::VisitParameterValue(HParameterValue* instruction) { diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc index a0383826d3..24234e18c1 100644 --- a/compiler/optimizing/code_generator_mips.cc +++ b/compiler/optimizing/code_generator_mips.cc @@ -5897,14 +5897,21 @@ void LocationsBuilderMIPS::VisitNewArray(HNewArray* instruction) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kCallOnMainOnly); InvokeRuntimeCallingConvention calling_convention; + locations->AddTemp(Location::RegisterLocation(calling_convention.GetRegisterAt(0))); + locations->AddTemp(Location::RegisterLocation(calling_convention.GetRegisterAt(2))); locations->SetOut(calling_convention.GetReturnLocation(Primitive::kPrimNot)); - locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0))); - locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(1))); + locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(1))); } void InstructionCodeGeneratorMIPS::VisitNewArray(HNewArray* instruction) { - codegen_->InvokeRuntime(kQuickAllocArrayResolved, instruction, instruction->GetDexPc()); - CheckEntrypointTypes<kQuickAllocArrayResolved, void*, mirror::Class*, int32_t>(); + InvokeRuntimeCallingConvention calling_convention; + Register current_method_register = calling_convention.GetRegisterAt(2); + __ Lw(current_method_register, SP, kCurrentMethodStackOffset); + // Move an uint16_t value to a register. + __ LoadConst32(calling_convention.GetRegisterAt(0), instruction->GetTypeIndex().index_); + codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); + CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck, + void*, uint32_t, int32_t, ArtMethod*>(); } void LocationsBuilderMIPS::VisitNewInstance(HNewInstance* instruction) { diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc index 446dea659e..fc8fb7acb2 100644 --- a/compiler/optimizing/code_generator_mips64.cc +++ b/compiler/optimizing/code_generator_mips64.cc @@ -3841,14 +3841,19 @@ void LocationsBuilderMIPS64::VisitNewArray(HNewArray* instruction) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kCallOnMainOnly); InvokeRuntimeCallingConvention calling_convention; + locations->AddTemp(Location::RegisterLocation(calling_convention.GetRegisterAt(0))); locations->SetOut(calling_convention.GetReturnLocation(Primitive::kPrimNot)); - locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0))); - locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(1))); + locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(1))); + locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(2))); } void InstructionCodeGeneratorMIPS64::VisitNewArray(HNewArray* instruction) { - codegen_->InvokeRuntime(kQuickAllocArrayResolved, instruction, instruction->GetDexPc()); - CheckEntrypointTypes<kQuickAllocArrayResolved, void*, mirror::Class*, int32_t>(); + LocationSummary* locations = instruction->GetLocations(); + // Move an uint16_t value to a register. + __ LoadConst32(locations->GetTemp(0).AsRegister<GpuRegister>(), + instruction->GetTypeIndex().index_); + codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); + CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck, void*, uint32_t, int32_t, ArtMethod*>(); } void LocationsBuilderMIPS64::VisitNewInstance(HNewInstance* instruction) { diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 853c91fac8..cc727d2068 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -4192,15 +4192,18 @@ void LocationsBuilderX86::VisitNewArray(HNewArray* instruction) { new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kCallOnMainOnly); locations->SetOut(Location::RegisterLocation(EAX)); InvokeRuntimeCallingConvention calling_convention; - locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0))); - locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(1))); + locations->AddTemp(Location::RegisterLocation(calling_convention.GetRegisterAt(0))); + locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(1))); + locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(2))); } void InstructionCodeGeneratorX86::VisitNewArray(HNewArray* instruction) { + InvokeRuntimeCallingConvention calling_convention; + __ movl(calling_convention.GetRegisterAt(0), Immediate(instruction->GetTypeIndex().index_)); // Note: if heap poisoning is enabled, the entry point takes cares // of poisoning the reference. - codegen_->InvokeRuntime(kQuickAllocArrayResolved, instruction, instruction->GetDexPc()); - CheckEntrypointTypes<kQuickAllocArrayResolved, void*, mirror::Class*, int32_t>(); + codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); + CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck, void*, uint32_t, int32_t, ArtMethod*>(); DCHECK(!codegen_->IsLeafMethod()); } diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index 74c71cce1f..9adedab130 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -4088,16 +4088,21 @@ void LocationsBuilderX86_64::VisitNewArray(HNewArray* instruction) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kCallOnMainOnly); InvokeRuntimeCallingConvention calling_convention; + locations->AddTemp(Location::RegisterLocation(calling_convention.GetRegisterAt(0))); locations->SetOut(Location::RegisterLocation(RAX)); - locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0))); - locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(1))); + locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(1))); + locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(2))); } void InstructionCodeGeneratorX86_64::VisitNewArray(HNewArray* instruction) { + InvokeRuntimeCallingConvention calling_convention; + codegen_->Load64BitValue(CpuRegister(calling_convention.GetRegisterAt(0)), + instruction->GetTypeIndex().index_); // Note: if heap poisoning is enabled, the entry point takes cares // of poisoning the reference. - codegen_->InvokeRuntime(kQuickAllocArrayResolved, instruction, instruction->GetDexPc()); - CheckEntrypointTypes<kQuickAllocArrayResolved, void*, mirror::Class*, int32_t>(); + codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); + CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck, void*, uint32_t, int32_t, ArtMethod*>(); + DCHECK(!codegen_->IsLeafMethod()); } diff --git a/compiler/optimizing/induction_var_range.cc b/compiler/optimizing/induction_var_range.cc index 3973985338..6d8ae75460 100644 --- a/compiler/optimizing/induction_var_range.cc +++ b/compiler/optimizing/induction_var_range.cc @@ -114,7 +114,12 @@ static bool IsMaxAtHint( } } else { *suitable = instruction; - return HuntForDeclaration(instruction) == hint; + while (instruction->IsArrayLength() || + instruction->IsNullCheck() || + instruction->IsNewArray()) { + instruction = instruction->InputAt(0); + } + return instruction == hint; } return false; } @@ -624,7 +629,7 @@ InductionVarRange::Value InductionVarRange::GetFetch(HInstruction* instruction, if (chase_hint_ == nullptr) { return is_min ? Value(0) : Value(std::numeric_limits<int32_t>::max()); } else if (instruction->InputAt(0)->IsNewArray()) { - return GetFetch(instruction->InputAt(0)->AsNewArray()->GetLength(), trip, in_body, is_min); + return GetFetch(instruction->InputAt(0)->InputAt(0), trip, in_body, is_min); } } else if (instruction->IsTypeConversion()) { // Since analysis is 32-bit (or narrower), chase beyond widening along the path. diff --git a/compiler/optimizing/induction_var_range_test.cc b/compiler/optimizing/induction_var_range_test.cc index d81817fb09..aa3e1aab4f 100644 --- a/compiler/optimizing/induction_var_range_test.cc +++ b/compiler/optimizing/induction_var_range_test.cc @@ -697,8 +697,13 @@ TEST_F(InductionVarRangeTest, MaxValue) { } TEST_F(InductionVarRangeTest, ArrayLengthAndHints) { - // We pass a bogus constant for the class to avoid mocking one. - HInstruction* new_array = new (&allocator_) HNewArray(x_, x_, 0); + HInstruction* new_array = new (&allocator_) + HNewArray(x_, + graph_->GetCurrentMethod(), + 0, + dex::TypeIndex(Primitive::kPrimInt), + graph_->GetDexFile(), + kQuickAllocArray); entry_block_->AddInstruction(new_array); HInstruction* array_length = new (&allocator_) HArrayLength(new_array, 0); entry_block_->AddInstruction(array_length); diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index 5d40f75618..78a4251e3a 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -1429,6 +1429,15 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, return false; } + if (current->IsNewArray() && + (current->AsNewArray()->GetEntrypoint() == kQuickAllocArrayWithAccessCheck)) { + VLOG(compiler) << "Method " << callee_dex_file.PrettyMethod(method_index) + << " could not be inlined because it is using an entrypoint" + << " with access checks"; + // Allocation entrypoint does not handle inlined frames. + return false; + } + if (current->IsUnresolvedStaticFieldGet() || current->IsUnresolvedInstanceFieldGet() || current->IsUnresolvedStaticFieldSet() || diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 48653cfeb9..8ed0e7fa06 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -1498,8 +1498,16 @@ void HInstructionBuilder::BuildFilledNewArray(uint32_t dex_pc, uint32_t* args, uint32_t register_index) { HInstruction* length = graph_->GetIntConstant(number_of_vreg_arguments, dex_pc); - HLoadClass* cls = BuildLoadClass(type_index, dex_pc, /* check_access */ true); - HInstruction* object = new (arena_) HNewArray(cls, length, dex_pc); + bool finalizable; + QuickEntrypointEnum entrypoint = NeedsAccessCheck(type_index, &finalizable) + ? kQuickAllocArrayWithAccessCheck + : kQuickAllocArray; + HInstruction* object = new (arena_) HNewArray(length, + graph_->GetCurrentMethod(), + dex_pc, + type_index, + *dex_compilation_unit_->GetDexFile(), + entrypoint); AppendInstruction(object); const char* descriptor = dex_file_->StringByTypeIdx(type_index); @@ -2495,8 +2503,16 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, case Instruction::NEW_ARRAY: { dex::TypeIndex type_index(instruction.VRegC_22c()); HInstruction* length = LoadLocal(instruction.VRegB_22c(), Primitive::kPrimInt); - HLoadClass* cls = BuildLoadClass(type_index, dex_pc, /* check_access */ true); - AppendInstruction(new (arena_) HNewArray(cls, length, dex_pc)); + bool finalizable; + QuickEntrypointEnum entrypoint = NeedsAccessCheck(type_index, &finalizable) + ? kQuickAllocArrayWithAccessCheck + : kQuickAllocArray; + AppendInstruction(new (arena_) HNewArray(length, + graph_->GetCurrentMethod(), + dex_pc, + type_index, + *dex_compilation_unit_->GetDexFile(), + entrypoint)); UpdateLocal(instruction.VRegA_22c(), current_block_->GetLastInstruction()); break; } diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc index 35f59cb4a4..911bfb9cc6 100644 --- a/compiler/optimizing/instruction_simplifier.cc +++ b/compiler/optimizing/instruction_simplifier.cc @@ -777,7 +777,7 @@ void InstructionSimplifierVisitor::VisitArrayLength(HArrayLength* instruction) { // If the array is a NewArray with constant size, replace the array length // with the constant instruction. This helps the bounds check elimination phase. if (input->IsNewArray()) { - input = input->AsNewArray()->GetLength(); + input = input->InputAt(0); if (input->IsIntConstant()) { instruction->ReplaceWith(input); } @@ -1774,7 +1774,7 @@ static bool IsArrayLengthOf(HInstruction* potential_length, HInstruction* potent } if (potential_array->IsNewArray()) { - return potential_array->AsNewArray()->GetLength() == potential_length; + return potential_array->InputAt(0) == potential_length; } return false; diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index a2980dca20..53b0fdde75 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -3801,15 +3801,6 @@ class HNewInstance FINAL : public HExpression<1> { entrypoint_ = entrypoint; } - HLoadClass* GetLoadClass() const { - HInstruction* input = InputAt(0); - if (input->IsClinitCheck()) { - input = input->InputAt(0); - } - DCHECK(input->IsLoadClass()); - return input->AsLoadClass(); - } - bool IsStringAlloc() const; DECLARE_INSTRUCTION(NewInstance); @@ -4364,12 +4355,23 @@ class HNeg FINAL : public HUnaryOperation { class HNewArray FINAL : public HExpression<2> { public: - HNewArray(HInstruction* cls, HInstruction* length, uint32_t dex_pc) - : HExpression(Primitive::kPrimNot, SideEffects::CanTriggerGC(), dex_pc) { - SetRawInputAt(0, cls); - SetRawInputAt(1, length); + HNewArray(HInstruction* length, + HCurrentMethod* current_method, + uint32_t dex_pc, + dex::TypeIndex type_index, + const DexFile& dex_file, + QuickEntrypointEnum entrypoint) + : HExpression(Primitive::kPrimNot, SideEffects::CanTriggerGC(), dex_pc), + type_index_(type_index), + dex_file_(dex_file), + entrypoint_(entrypoint) { + SetRawInputAt(0, length); + SetRawInputAt(1, current_method); } + dex::TypeIndex GetTypeIndex() const { return type_index_; } + const DexFile& GetDexFile() const { return dex_file_; } + // Calls runtime so needs an environment. bool NeedsEnvironment() const OVERRIDE { return true; } @@ -4378,18 +4380,15 @@ class HNewArray FINAL : public HExpression<2> { bool CanBeNull() const OVERRIDE { return false; } - HLoadClass* GetLoadClass() const { - DCHECK(InputAt(0)->IsLoadClass()); - return InputAt(0)->AsLoadClass(); - } - - HInstruction* GetLength() const { - return InputAt(1); - } + QuickEntrypointEnum GetEntrypoint() const { return entrypoint_; } DECLARE_INSTRUCTION(NewArray); private: + const dex::TypeIndex type_index_; + const DexFile& dex_file_; + const QuickEntrypointEnum entrypoint_; + DISALLOW_COPY_AND_ASSIGN(HNewArray); }; @@ -5892,10 +5891,7 @@ class HClinitCheck FINAL : public HExpression<1> { bool CanThrow() const OVERRIDE { return true; } - HLoadClass* GetLoadClass() const { - DCHECK(InputAt(0)->IsLoadClass()); - return InputAt(0)->AsLoadClass(); - } + HLoadClass* GetLoadClass() const { return InputAt(0)->AsLoadClass(); } DECLARE_INSTRUCTION(ClinitCheck); @@ -6761,23 +6757,6 @@ inline void MakeRoomFor(ArenaVector<HBasicBlock*>* blocks, std::copy_backward(blocks->begin() + after + 1u, blocks->begin() + old_size, blocks->end()); } -/* - * Hunt "under the hood" of array lengths (leading to array references), - * null checks (also leading to array references), and new arrays - * (leading to the actual length). This makes it more likely related - * instructions become actually comparable. - */ -inline HInstruction* HuntForDeclaration(HInstruction* instruction) { - while (instruction->IsArrayLength() || - instruction->IsNullCheck() || - instruction->IsNewArray()) { - instruction = instruction->IsNewArray() - ? instruction->AsNewArray()->GetLength() - : instruction->InputAt(0); - } - return instruction; -} - } // namespace art #endif // ART_COMPILER_OPTIMIZING_NODES_H_ diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc index b02f2509ab..8854a2b08b 100644 --- a/compiler/optimizing/reference_type_propagation.cc +++ b/compiler/optimizing/reference_type_propagation.cc @@ -548,13 +548,11 @@ void ReferenceTypePropagation::RTPVisitor::UpdateReferenceTypeInfo(HInstruction* } void ReferenceTypePropagation::RTPVisitor::VisitNewInstance(HNewInstance* instr) { - ScopedObjectAccess soa(Thread::Current()); - SetClassAsTypeInfo(instr, instr->GetLoadClass()->GetClass().Get(), /* is_exact */ true); + UpdateReferenceTypeInfo(instr, instr->GetTypeIndex(), instr->GetDexFile(), /* is_exact */ true); } void ReferenceTypePropagation::RTPVisitor::VisitNewArray(HNewArray* instr) { - ScopedObjectAccess soa(Thread::Current()); - SetClassAsTypeInfo(instr, instr->GetLoadClass()->GetClass().Get(), /* is_exact */ true); + UpdateReferenceTypeInfo(instr, instr->GetTypeIndex(), instr->GetDexFile(), /* is_exact */ true); } static mirror::Class* GetClassFromDexCache(Thread* self, |