diff options
Diffstat (limited to 'compiler/optimizing')
| -rw-r--r-- | compiler/optimizing/block_builder.cc | 1 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_utils.cc | 5 | ||||
| -rw-r--r-- | compiler/optimizing/data_type.h | 3 | ||||
| -rw-r--r-- | compiler/optimizing/inliner.cc | 6 | ||||
| -rw-r--r-- | compiler/optimizing/instruction_builder.cc | 35 | ||||
| -rw-r--r-- | compiler/optimizing/instruction_builder.h | 11 | ||||
| -rw-r--r-- | compiler/optimizing/loop_optimization.cc | 3 | ||||
| -rw-r--r-- | compiler/optimizing/nodes.cc | 30 | ||||
| -rw-r--r-- | compiler/optimizing/nodes.h | 29 | ||||
| -rw-r--r-- | compiler/optimizing/nodes_vector.h | 15 | ||||
| -rw-r--r-- | compiler/optimizing/optimization.cc | 3 | ||||
| -rw-r--r-- | compiler/optimizing/optimizing_compiler_stats.h | 1 | ||||
| -rw-r--r-- | compiler/optimizing/reference_type_propagation.cc | 2 | ||||
| -rw-r--r-- | compiler/optimizing/sharpening.cc | 38 | ||||
| -rw-r--r-- | compiler/optimizing/sharpening.h | 19 | ||||
| -rw-r--r-- | compiler/optimizing/ssa_liveness_analysis.cc | 7 |
16 files changed, 117 insertions, 91 deletions
diff --git a/compiler/optimizing/block_builder.cc b/compiler/optimizing/block_builder.cc index ed000327ff..58f591bd1e 100644 --- a/compiler/optimizing/block_builder.cc +++ b/compiler/optimizing/block_builder.cc @@ -16,6 +16,7 @@ #include "block_builder.h" +#include "base/logging.h" // FOR VLOG. #include "bytecode_utils.h" #include "quicken_info.h" diff --git a/compiler/optimizing/code_generator_utils.cc b/compiler/optimizing/code_generator_utils.cc index 96fe2a17e6..dd47a1fc6c 100644 --- a/compiler/optimizing/code_generator_utils.cc +++ b/compiler/optimizing/code_generator_utils.cc @@ -15,9 +15,10 @@ */ #include "code_generator_utils.h" -#include "nodes.h" -#include "base/logging.h" +#include <android-base/logging.h> + +#include "nodes.h" namespace art { diff --git a/compiler/optimizing/data_type.h b/compiler/optimizing/data_type.h index d253036479..548fe28cee 100644 --- a/compiler/optimizing/data_type.h +++ b/compiler/optimizing/data_type.h @@ -19,7 +19,8 @@ #include <iosfwd> -#include "base/logging.h" +#include <android-base/logging.h> + #include "base/bit_utils.h" namespace art { diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index 560372e22e..a175c21760 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -876,9 +876,9 @@ HInstruction* HInliner::AddTypeGuard(HInstruction* receiver, load_class, codegen_, compiler_driver_, caller_compilation_unit_); DCHECK(kind != HLoadClass::LoadKind::kInvalid) << "We should always be able to reference a class for inline caches"; - // Insert before setting the kind, as setting the kind affects the inputs. - bb_cursor->InsertInstructionAfter(load_class, receiver_class); + // Load kind must be set before inserting the instruction into the graph. load_class->SetLoadKind(kind); + bb_cursor->InsertInstructionAfter(load_class, receiver_class); // In AOT mode, we will most likely load the class from BSS, which will involve a call // to the runtime. In this case, the load instruction will need an environment so copy // it from the invoke instruction. @@ -1932,7 +1932,7 @@ void HInliner::RunOptimizations(HGraph* callee_graph, // optimization that could lead to a HDeoptimize. The following optimizations do not. HDeadCodeElimination dce(callee_graph, inline_stats_, "dead_code_elimination$inliner"); HConstantFolding fold(callee_graph, "constant_folding$inliner"); - HSharpening sharpening(callee_graph, codegen_, dex_compilation_unit, compiler_driver_, handles_); + HSharpening sharpening(callee_graph, codegen_, compiler_driver_); InstructionSimplifier simplify(callee_graph, codegen_, compiler_driver_, inline_stats_); IntrinsicsRecognizer intrinsics(callee_graph, inline_stats_); diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 782546c9d8..4485f064c6 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -1128,7 +1128,7 @@ void HInstructionBuilder::BuildConstructorFenceForAllocation(HInstruction* alloc MethodCompilationStat::kConstructorFenceGeneratedNew); } -static bool IsSubClass(mirror::Class* to_test, mirror::Class* super_class) +static bool IsSubClass(ObjPtr<mirror::Class> to_test, ObjPtr<mirror::Class> super_class) REQUIRES_SHARED(Locks::mutator_lock_) { return to_test != nullptr && !to_test->IsInterface() && to_test->IsSubClass(super_class); } @@ -1424,7 +1424,7 @@ bool HInstructionBuilder::BuildInstanceFieldAccess(const Instruction& instructio return true; } -static mirror::Class* GetClassFrom(CompilerDriver* driver, +static ObjPtr<mirror::Class> GetClassFrom(CompilerDriver* driver, const DexCompilationUnit& compilation_unit) { ScopedObjectAccess soa(Thread::Current()); Handle<mirror::ClassLoader> class_loader = compilation_unit.GetClassLoader(); @@ -1433,11 +1433,11 @@ static mirror::Class* GetClassFrom(CompilerDriver* driver, return driver->ResolveCompilingMethodsClass(soa, dex_cache, class_loader, &compilation_unit); } -mirror::Class* HInstructionBuilder::GetOutermostCompilingClass() const { +ObjPtr<mirror::Class> HInstructionBuilder::GetOutermostCompilingClass() const { return GetClassFrom(compiler_driver_, *outer_compilation_unit_); } -mirror::Class* HInstructionBuilder::GetCompilingClass() const { +ObjPtr<mirror::Class> HInstructionBuilder::GetCompilingClass() const { return GetClassFrom(compiler_driver_, *dex_compilation_unit_); } @@ -1799,6 +1799,17 @@ static TypeCheckKind ComputeTypeCheckKind(Handle<mirror::Class> cls) } } +void HInstructionBuilder::BuildLoadString(dex::StringIndex string_index, uint32_t dex_pc) { + HLoadString* load_string = + new (allocator_) HLoadString(graph_->GetCurrentMethod(), string_index, *dex_file_, dex_pc); + HSharpening::ProcessLoadString(load_string, + code_generator_, + compiler_driver_, + *dex_compilation_unit_, + handles_); + AppendInstruction(load_string); +} + HLoadClass* HInstructionBuilder::BuildLoadClass(dex::TypeIndex type_index, uint32_t dex_pc) { ScopedObjectAccess soa(Thread::Current()); const DexFile& dex_file = *dex_compilation_unit_->GetDexFile(); @@ -1811,7 +1822,7 @@ HLoadClass* HInstructionBuilder::BuildLoadClass(dex::TypeIndex type_index, uint3 if (klass->IsPublic()) { needs_access_check = false; } else { - mirror::Class* compiling_class = GetCompilingClass(); + ObjPtr<mirror::Class> compiling_class = GetCompilingClass(); if (compiling_class != nullptr && compiling_class->CanAccess(klass.Get())) { needs_access_check = false; } @@ -1856,9 +1867,9 @@ HLoadClass* HInstructionBuilder::BuildLoadClass(dex::TypeIndex type_index, // We actually cannot reference this class, we're forced to bail. return nullptr; } - // Append the instruction first, as setting the load kind affects the inputs. - AppendInstruction(load_class); + // Load kind must be set before inserting the instruction into the graph. load_class->SetLoadKind(load_kind); + AppendInstruction(load_class); return load_class; } @@ -2837,20 +2848,14 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, case Instruction::CONST_STRING: { dex::StringIndex string_index(instruction.VRegB_21c()); - AppendInstruction(new (allocator_) HLoadString(graph_->GetCurrentMethod(), - string_index, - *dex_file_, - dex_pc)); + BuildLoadString(string_index, dex_pc); UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction()); break; } case Instruction::CONST_STRING_JUMBO: { dex::StringIndex string_index(instruction.VRegB_31c()); - AppendInstruction(new (allocator_) HLoadString(graph_->GetCurrentMethod(), - string_index, - *dex_file_, - dex_pc)); + BuildLoadString(string_index, dex_pc); UpdateLocal(instruction.VRegA_31c(), current_block_->GetLastInstruction()); break; } diff --git a/compiler/optimizing/instruction_builder.h b/compiler/optimizing/instruction_builder.h index 2446ddb86a..0500d40cd3 100644 --- a/compiler/optimizing/instruction_builder.h +++ b/compiler/optimizing/instruction_builder.h @@ -240,9 +240,10 @@ class HInstructionBuilder : public ValueObject { // Builds an instruction sequence for a switch statement. void BuildSwitch(const Instruction& instruction, uint32_t dex_pc); - // Builds a `HLoadClass` loading the given `type_index`. If `outer` is true, - // this method will use the outer class's dex file to lookup the type at - // `type_index`. + // Builds a `HLoadString` loading the given `string_index`. + void BuildLoadString(dex::StringIndex string_index, uint32_t dex_pc); + + // Builds a `HLoadClass` loading the given `type_index`. HLoadClass* BuildLoadClass(dex::TypeIndex type_index, uint32_t dex_pc); HLoadClass* BuildLoadClass(dex::TypeIndex type_index, @@ -253,10 +254,10 @@ class HInstructionBuilder : public ValueObject { REQUIRES_SHARED(Locks::mutator_lock_); // Returns the outer-most compiling method's class. - mirror::Class* GetOutermostCompilingClass() const; + ObjPtr<mirror::Class> GetOutermostCompilingClass() const; // Returns the class whose method is being compiled. - mirror::Class* GetCompilingClass() const; + ObjPtr<mirror::Class> GetCompilingClass() const; // Returns whether `type_index` points to the outer-most compiling method's class. bool IsOutermostCompilingClass(dex::TypeIndex type_index) const; diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc index 1ca096035e..3dc1ef7534 100644 --- a/compiler/optimizing/loop_optimization.cc +++ b/compiler/optimizing/loop_optimization.cc @@ -1749,7 +1749,8 @@ void HLoopOptimization::GenerateVecReductionPhiInputs(HPhi* phi, HInstruction* r HInstruction* HLoopOptimization::ReduceAndExtractIfNeeded(HInstruction* instruction) { if (instruction->IsPhi()) { HInstruction* input = instruction->InputAt(1); - if (input->IsVecOperation() && !input->IsVecExtractScalar()) { + if (HVecOperation::ReturnsSIMDValue(input)) { + DCHECK(!input->IsPhi()); HVecOperation* input_vector = input->AsVecOperation(); uint32_t vector_length = input_vector->GetVectorLength(); DataType::Type type = input_vector->GetPackedType(); diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index d117bfb67d..5f33ed6303 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -2831,21 +2831,6 @@ bool HLoadClass::InstructionDataEquals(const HInstruction* other) const { } } -void HLoadClass::SetLoadKind(LoadKind load_kind) { - SetPackedField<LoadKindField>(load_kind); - - if (load_kind != LoadKind::kRuntimeCall && - load_kind != LoadKind::kReferrersClass) { - RemoveAsUserOfInput(0u); - SetRawInputAt(0u, nullptr); - } - - if (!NeedsEnvironment()) { - RemoveEnvironment(); - SetSideEffects(SideEffects::None()); - } -} - std::ostream& operator<<(std::ostream& os, HLoadClass::LoadKind rhs) { switch (rhs) { case HLoadClass::LoadKind::kReferrersClass: @@ -2888,21 +2873,6 @@ bool HLoadString::InstructionDataEquals(const HInstruction* other) const { } } -void HLoadString::SetLoadKind(LoadKind load_kind) { - // Once sharpened, the load kind should not be changed again. - DCHECK_EQ(GetLoadKind(), LoadKind::kRuntimeCall); - SetPackedField<LoadKindField>(load_kind); - - if (load_kind != LoadKind::kRuntimeCall) { - RemoveAsUserOfInput(0u); - SetRawInputAt(0u, nullptr); - } - if (!NeedsEnvironment()) { - RemoveEnvironment(); - SetSideEffects(SideEffects::None()); - } -} - std::ostream& operator<<(std::ostream& os, HLoadString::LoadKind rhs) { switch (rhs) { case HLoadString::LoadKind::kBootImageLinkTimePcRelative: diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 7fbd7f48a2..42a9d95b9a 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -6061,6 +6061,20 @@ class HLoadClass FINAL : public HInstruction { std::ostream& operator<<(std::ostream& os, HLoadClass::LoadKind rhs); // Note: defined outside class to see operator<<(., HLoadClass::LoadKind). +inline void HLoadClass::SetLoadKind(LoadKind load_kind) { + // The load kind should be determined before inserting the instruction to the graph. + DCHECK(GetBlock() == nullptr); + DCHECK(GetEnvironment() == nullptr); + SetPackedField<LoadKindField>(load_kind); + if (load_kind != LoadKind::kRuntimeCall && load_kind != LoadKind::kReferrersClass) { + special_input_ = HUserRecord<HInstruction*>(nullptr); + } + if (!NeedsEnvironment()) { + SetSideEffects(SideEffects::None()); + } +} + +// Note: defined outside class to see operator<<(., HLoadClass::LoadKind). inline void HLoadClass::AddSpecialInput(HInstruction* special_input) { // The special input is used for PC-relative loads on some architectures, // including literal pool loads, which are PC-relative too. @@ -6208,6 +6222,21 @@ class HLoadString FINAL : public HInstruction { std::ostream& operator<<(std::ostream& os, HLoadString::LoadKind rhs); // Note: defined outside class to see operator<<(., HLoadString::LoadKind). +inline void HLoadString::SetLoadKind(LoadKind load_kind) { + // The load kind should be determined before inserting the instruction to the graph. + DCHECK(GetBlock() == nullptr); + DCHECK(GetEnvironment() == nullptr); + DCHECK_EQ(GetLoadKind(), LoadKind::kRuntimeCall); + SetPackedField<LoadKindField>(load_kind); + if (load_kind != LoadKind::kRuntimeCall) { + special_input_ = HUserRecord<HInstruction*>(nullptr); + } + if (!NeedsEnvironment()) { + SetSideEffects(SideEffects::None()); + } +} + +// Note: defined outside class to see operator<<(., HLoadString::LoadKind). inline void HLoadString::AddSpecialInput(HInstruction* special_input) { // The special input is used for PC-relative loads on some architectures, // including literal pool loads, which are PC-relative too. diff --git a/compiler/optimizing/nodes_vector.h b/compiler/optimizing/nodes_vector.h index 59d5b9f847..096349fd73 100644 --- a/compiler/optimizing/nodes_vector.h +++ b/compiler/optimizing/nodes_vector.h @@ -150,6 +150,19 @@ class HVecOperation : public HVariableInputSizeInstruction { } } + // Helper method to determine if an instruction returns a SIMD value. + // TODO: This method is needed until we introduce SIMD as proper type. + static bool ReturnsSIMDValue(HInstruction* instruction) { + if (instruction->IsVecOperation()) { + return !instruction->IsVecExtractScalar(); // only scalar returning vec op + } else if (instruction->IsPhi()) { + return + instruction->GetType() == kSIMDType && + instruction->InputAt(1)->IsVecOperation(); // vectorizer does not go deeper + } + return false; + } + DECLARE_ABSTRACT_INSTRUCTION(VecOperation); protected: @@ -879,7 +892,7 @@ class HVecSetScalars FINAL : public HVecOperation { vector_length, dex_pc) { for (size_t i = 0; i < number_of_scalars; i++) { - DCHECK(!scalars[i]->IsVecOperation() || scalars[i]->IsVecExtractScalar()); + DCHECK(!ReturnsSIMDValue(scalars[i])); SetRawInputAt(0, scalars[i]); } } diff --git a/compiler/optimizing/optimization.cc b/compiler/optimizing/optimization.cc index 7edb642c5b..7149d93d07 100644 --- a/compiler/optimizing/optimization.cc +++ b/compiler/optimizing/optimization.cc @@ -258,8 +258,7 @@ ArenaVector<HOptimization*> ConstructOptimizations( break; } case OptimizationPass::kSharpening: - opt = new (allocator) HSharpening( - graph, codegen, dex_compilation_unit, driver, handles, name); + opt = new (allocator) HSharpening(graph, codegen, driver, name); break; case OptimizationPass::kSelectGenerator: opt = new (allocator) HSelectGenerator(graph, handles, stats, name); diff --git a/compiler/optimizing/optimizing_compiler_stats.h b/compiler/optimizing/optimizing_compiler_stats.h index a2e92d2931..32a94ab5e4 100644 --- a/compiler/optimizing/optimizing_compiler_stats.h +++ b/compiler/optimizing/optimizing_compiler_stats.h @@ -23,6 +23,7 @@ #include <type_traits> #include "atomic.h" +#include "base/logging.h" // For VLOG_IS_ON. #include "globals.h" namespace art { diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc index 7246129e25..d84f14acc0 100644 --- a/compiler/optimizing/reference_type_propagation.cc +++ b/compiler/optimizing/reference_type_propagation.cc @@ -612,7 +612,7 @@ void ReferenceTypePropagation::RTPVisitor::UpdateFieldAccessTypeInfo(HInstructio // The field is unknown only during tests. if (info.GetField() != nullptr) { - klass = info.GetField()->LookupType(); + klass = info.GetField()->LookupResolvedType(); } SetClassAsTypeInfo(instr, klass, /* is_exact */ false); diff --git a/compiler/optimizing/sharpening.cc b/compiler/optimizing/sharpening.cc index e46c9a7081..64092d307d 100644 --- a/compiler/optimizing/sharpening.cc +++ b/compiler/optimizing/sharpening.cc @@ -45,8 +45,6 @@ void HSharpening::Run() { SharpenInvokeStaticOrDirect(instruction->AsInvokeStaticOrDirect(), codegen_, compiler_driver_); - } else if (instruction->IsLoadString()) { - ProcessLoadString(instruction->AsLoadString()); } // TODO: Move the sharpening of invoke-virtual/-interface/-super from HGraphBuilder // here. Rewrite it to avoid the CompilerDriver's reliance on verifier data @@ -147,10 +145,11 @@ void HSharpening::SharpenInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke, invoke->SetDispatchInfo(dispatch_info); } -HLoadClass::LoadKind HSharpening::ComputeLoadClassKind(HLoadClass* load_class, - CodeGenerator* codegen, - CompilerDriver* compiler_driver, - const DexCompilationUnit& dex_compilation_unit) { +HLoadClass::LoadKind HSharpening::ComputeLoadClassKind( + HLoadClass* load_class, + CodeGenerator* codegen, + CompilerDriver* compiler_driver, + const DexCompilationUnit& dex_compilation_unit) { Handle<mirror::Class> klass = load_class->GetClass(); DCHECK(load_class->GetLoadKind() == HLoadClass::LoadKind::kRuntimeCall || load_class->GetLoadKind() == HLoadClass::LoadKind::kReferrersClass) @@ -237,7 +236,12 @@ HLoadClass::LoadKind HSharpening::ComputeLoadClassKind(HLoadClass* load_class, return load_kind; } -void HSharpening::ProcessLoadString(HLoadString* load_string) { +void HSharpening::ProcessLoadString( + HLoadString* load_string, + CodeGenerator* codegen, + CompilerDriver* compiler_driver, + const DexCompilationUnit& dex_compilation_unit, + VariableSizedHandleScope* handles) { DCHECK_EQ(load_string->GetLoadKind(), HLoadString::LoadKind::kRuntimeCall); const DexFile& dex_file = load_string->GetDexFile(); @@ -249,26 +253,26 @@ void HSharpening::ProcessLoadString(HLoadString* load_string) { ClassLinker* class_linker = runtime->GetClassLinker(); ScopedObjectAccess soa(Thread::Current()); StackHandleScope<1> hs(soa.Self()); - Handle<mirror::DexCache> dex_cache = IsSameDexFile(dex_file, *compilation_unit_.GetDexFile()) - ? compilation_unit_.GetDexCache() + Handle<mirror::DexCache> dex_cache = IsSameDexFile(dex_file, *dex_compilation_unit.GetDexFile()) + ? dex_compilation_unit.GetDexCache() : hs.NewHandle(class_linker->FindDexCache(soa.Self(), dex_file)); - mirror::String* string = nullptr; + ObjPtr<mirror::String> string = nullptr; - if (codegen_->GetCompilerOptions().IsBootImage()) { + if (codegen->GetCompilerOptions().IsBootImage()) { // Compiling boot image. Resolve the string and allocate it if needed, to ensure // the string will be added to the boot image. DCHECK(!runtime->UseJitCompilation()); string = class_linker->ResolveString(dex_file, string_index, dex_cache); CHECK(string != nullptr); - if (compiler_driver_->GetSupportBootImageFixup()) { - DCHECK(ContainsElement(compiler_driver_->GetDexFilesForOatFile(), &dex_file)); + if (compiler_driver->GetSupportBootImageFixup()) { + DCHECK(ContainsElement(compiler_driver->GetDexFilesForOatFile(), &dex_file)); desired_load_kind = HLoadString::LoadKind::kBootImageLinkTimePcRelative; } else { // compiler_driver_test. Do not sharpen. desired_load_kind = HLoadString::LoadKind::kRuntimeCall; } } else if (runtime->UseJitCompilation()) { - DCHECK(!codegen_->GetCompilerOptions().GetCompilePic()); + DCHECK(!codegen->GetCompilerOptions().GetCompilePic()); string = class_linker->LookupString(dex_file, string_index, dex_cache.Get()); if (string != nullptr) { if (runtime->GetHeap()->ObjectIsInBootImageSpace(string)) { @@ -283,7 +287,7 @@ void HSharpening::ProcessLoadString(HLoadString* load_string) { // AOT app compilation. Try to lookup the string without allocating if not found. string = class_linker->LookupString(dex_file, string_index, dex_cache.Get()); if (string != nullptr && runtime->GetHeap()->ObjectIsInBootImageSpace(string)) { - if (codegen_->GetCompilerOptions().GetCompilePic()) { + if (codegen->GetCompilerOptions().GetCompilePic()) { desired_load_kind = HLoadString::LoadKind::kBootImageInternTable; } else { desired_load_kind = HLoadString::LoadKind::kBootImageAddress; @@ -293,12 +297,12 @@ void HSharpening::ProcessLoadString(HLoadString* load_string) { } } if (string != nullptr) { - load_string->SetString(handles_->NewHandle(string)); + load_string->SetString(handles->NewHandle(string)); } } DCHECK_NE(desired_load_kind, static_cast<HLoadString::LoadKind>(-1)); - HLoadString::LoadKind load_kind = codegen_->GetSupportedLoadStringKind(desired_load_kind); + HLoadString::LoadKind load_kind = codegen->GetSupportedLoadStringKind(desired_load_kind); load_string->SetLoadKind(load_kind); } diff --git a/compiler/optimizing/sharpening.h b/compiler/optimizing/sharpening.h index bb1954eeeb..6df7d6d91e 100644 --- a/compiler/optimizing/sharpening.h +++ b/compiler/optimizing/sharpening.h @@ -34,26 +34,29 @@ class HSharpening : public HOptimization { public: HSharpening(HGraph* graph, CodeGenerator* codegen, - const DexCompilationUnit& compilation_unit, CompilerDriver* compiler_driver, - VariableSizedHandleScope* handles, const char* name = kSharpeningPassName) : HOptimization(graph, name), codegen_(codegen), - compilation_unit_(compilation_unit), - compiler_driver_(compiler_driver), - handles_(handles) { } + compiler_driver_(compiler_driver) { } void Run() OVERRIDE; static constexpr const char* kSharpeningPassName = "sharpening"; + // Used by the builder. + static void ProcessLoadString(HLoadString* load_string, + CodeGenerator* codegen, + CompilerDriver* compiler_driver, + const DexCompilationUnit& dex_compilation_unit, + VariableSizedHandleScope* handles); + // Used by the builder and the inliner. static HLoadClass::LoadKind ComputeLoadClassKind(HLoadClass* load_class, CodeGenerator* codegen, CompilerDriver* compiler_driver, const DexCompilationUnit& dex_compilation_unit) - REQUIRES_SHARED(Locks::mutator_lock_); + REQUIRES_SHARED(Locks::mutator_lock_); // Used by Sharpening and InstructionSimplifier. static void SharpenInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke, @@ -61,12 +64,8 @@ class HSharpening : public HOptimization { CompilerDriver* compiler_driver); private: - void ProcessLoadString(HLoadString* load_string); - CodeGenerator* codegen_; - const DexCompilationUnit& compilation_unit_; CompilerDriver* compiler_driver_; - VariableSizedHandleScope* handles_; }; } // namespace art diff --git a/compiler/optimizing/ssa_liveness_analysis.cc b/compiler/optimizing/ssa_liveness_analysis.cc index 9ab7a89b33..f6bd05269e 100644 --- a/compiler/optimizing/ssa_liveness_analysis.cc +++ b/compiler/optimizing/ssa_liveness_analysis.cc @@ -474,9 +474,10 @@ size_t LiveInterval::NumberOfSpillSlotsNeeded() const { // For a SIMD operation, compute the number of needed spill slots. // TODO: do through vector type? HInstruction* definition = GetParent()->GetDefinedBy(); - if (definition != nullptr && - definition->IsVecOperation() && - !definition->IsVecExtractScalar()) { + if (definition != nullptr && HVecOperation::ReturnsSIMDValue(definition)) { + if (definition->IsPhi()) { + definition = definition->InputAt(1); // SIMD always appears on back-edge + } return definition->AsVecOperation()->GetVectorNumberOfBytes() / kVRegSize; } // Return number of needed spill slots based on type. |