diff options
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 24 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm64.cc | 31 | ||||
-rw-r--r-- | compiler/optimizing/dead_code_elimination.h | 6 | ||||
-rw-r--r-- | compiler/optimizing/dex_cache_array_fixups_arm.h | 4 | ||||
-rw-r--r-- | compiler/optimizing/dex_cache_array_fixups_mips.h | 4 | ||||
-rw-r--r-- | compiler/optimizing/induction_var_analysis.h | 2 | ||||
-rw-r--r-- | compiler/optimizing/instruction_simplifier_arm.h | 4 | ||||
-rw-r--r-- | compiler/optimizing/instruction_simplifier_arm64.h | 5 | ||||
-rw-r--r-- | compiler/optimizing/instruction_simplifier_shared.cc | 16 | ||||
-rw-r--r-- | compiler/optimizing/optimization.h | 5 | ||||
-rw-r--r-- | compiler/optimizing/optimizing_compiler.cc | 188 | ||||
-rw-r--r-- | compiler/optimizing/pc_relative_fixups_mips.h | 2 | ||||
-rw-r--r-- | compiler/optimizing/pc_relative_fixups_x86.h | 4 | ||||
-rw-r--r-- | compiler/optimizing/x86_memory_gen.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/x86_memory_gen.h | 4 |
15 files changed, 225 insertions, 78 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index c105940f28..5eaf11e9fb 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -432,6 +432,11 @@ class ReadBarrierMarkSlowPathARM : public SlowPathCode { (instruction_->IsInvokeVirtual()) && instruction_->GetLocations()->Intrinsified()) << "Unexpected instruction in read barrier marking slow path: " << instruction_->DebugName(); + // The read barrier instrumentation of object ArrayGet + // instructions does not support the HIntermediateAddress + // instruction. + DCHECK(!(instruction_->IsArrayGet() && + instruction_->AsArrayGet()->GetArray()->IsIntermediateAddress())); __ Bind(GetEntryLabel()); // No need to save live registers; it's taken care of by the @@ -512,6 +517,11 @@ class ReadBarrierForHeapReferenceSlowPathARM : public SlowPathCode { (instruction_->IsInvokeVirtual()) && instruction_->GetLocations()->Intrinsified()) << "Unexpected instruction in read barrier for heap reference slow path: " << instruction_->DebugName(); + // The read barrier instrumentation of object ArrayGet + // instructions does not support the HIntermediateAddress + // instruction. + DCHECK(!(instruction_->IsArrayGet() && + instruction_->AsArrayGet()->GetArray()->IsIntermediateAddress())); __ Bind(GetEntryLabel()); SaveLiveRegisters(codegen, locations); @@ -4467,8 +4477,6 @@ void InstructionCodeGeneratorARM::VisitArrayGet(HArrayGet* instruction) { Primitive::Type type = instruction->GetType(); HInstruction* array_instr = instruction->GetArray(); bool has_intermediate_address = array_instr->IsIntermediateAddress(); - // The read barrier instrumentation does not support the HIntermediateAddress instruction yet. - DCHECK(!(has_intermediate_address && kEmitCompilerReadBarrier)); switch (type) { case Primitive::kPrimBoolean: @@ -4503,6 +4511,11 @@ void InstructionCodeGeneratorARM::VisitArrayGet(HArrayGet* instruction) { } case Primitive::kPrimNot: { + // The read barrier instrumentation of object ArrayGet + // instructions does not support the HIntermediateAddress + // instruction. + DCHECK(!(has_intermediate_address && kEmitCompilerReadBarrier)); + static_assert( sizeof(mirror::HeapReference<mirror::Object>) == sizeof(int32_t), "art::mirror::HeapReference<art::mirror::Object> and int32_t have different sizes."); @@ -4645,8 +4658,6 @@ void InstructionCodeGeneratorARM::VisitArraySet(HArraySet* instruction) { Location value_loc = locations->InAt(2); HInstruction* array_instr = instruction->GetArray(); bool has_intermediate_address = array_instr->IsIntermediateAddress(); - // The read barrier instrumentation does not support the HIntermediateAddress instruction yet. - DCHECK(!(has_intermediate_address && kEmitCompilerReadBarrier)); switch (value_type) { case Primitive::kPrimBoolean: @@ -4911,8 +4922,6 @@ void InstructionCodeGeneratorARM::VisitArrayLength(HArrayLength* instruction) { } void LocationsBuilderARM::VisitIntermediateAddress(HIntermediateAddress* instruction) { - // The read barrier instrumentation does not support the HIntermediateAddress instruction yet. - DCHECK(!kEmitCompilerReadBarrier); LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall); @@ -4927,9 +4936,6 @@ void InstructionCodeGeneratorARM::VisitIntermediateAddress(HIntermediateAddress* Location first = locations->InAt(0); Location second = locations->InAt(1); - // The read barrier instrumentation does not support the HIntermediateAddress instruction yet. - DCHECK(!kEmitCompilerReadBarrier); - if (second.IsRegister()) { __ add(out.AsRegister<Register>(), first.AsRegister<Register>(), diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index 54c9efcafe..9ceb3109cd 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -598,6 +598,11 @@ class ReadBarrierMarkSlowPathARM64 : public SlowPathCodeARM64 { (instruction_->IsInvokeVirtual()) && instruction_->GetLocations()->Intrinsified()) << "Unexpected instruction in read barrier marking slow path: " << instruction_->DebugName(); + // The read barrier instrumentation of object ArrayGet + // instructions does not support the HIntermediateAddress + // instruction. + DCHECK(!(instruction_->IsArrayGet() && + instruction_->AsArrayGet()->GetArray()->IsIntermediateAddress())); __ Bind(GetEntryLabel()); // No need to save live registers; it's taken care of by the @@ -680,7 +685,9 @@ class ReadBarrierForHeapReferenceSlowPathARM64 : public SlowPathCodeARM64 { (instruction_->IsInvokeVirtual()) && instruction_->GetLocations()->Intrinsified()) << "Unexpected instruction in read barrier for heap reference slow path: " << instruction_->DebugName(); - // The read barrier instrumentation does not support the HIntermediateAddress instruction yet. + // The read barrier instrumentation of object ArrayGet + // instructions does not support the HIntermediateAddress + // instruction. DCHECK(!(instruction_->IsArrayGet() && instruction_->AsArrayGet()->GetArray()->IsIntermediateAddress())); @@ -1983,8 +1990,6 @@ void InstructionCodeGeneratorARM64::VisitArm64DataProcWithShifterOp( } void LocationsBuilderARM64::VisitIntermediateAddress(HIntermediateAddress* instruction) { - // The read barrier instrumentation does not support the HIntermediateAddress instruction yet. - DCHECK(!kEmitCompilerReadBarrier); LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall); locations->SetInAt(0, Location::RequiresRegister()); @@ -1992,10 +1997,7 @@ void LocationsBuilderARM64::VisitIntermediateAddress(HIntermediateAddress* instr locations->SetOut(Location::RequiresRegister()); } -void InstructionCodeGeneratorARM64::VisitIntermediateAddress( - HIntermediateAddress* instruction) { - // The read barrier instrumentation does not support the HIntermediateAddress instruction yet. - DCHECK(!kEmitCompilerReadBarrier); +void InstructionCodeGeneratorARM64::VisitIntermediateAddress(HIntermediateAddress* instruction) { __ Add(OutputRegister(instruction), InputRegisterAt(instruction, 0), Operand(InputOperandAt(instruction, 1))); @@ -2091,11 +2093,15 @@ void InstructionCodeGeneratorARM64::VisitArrayGet(HArrayGet* instruction) { // Block pools between `Load` and `MaybeRecordImplicitNullCheck`. BlockPoolsScope block_pools(masm); + // The read barrier instrumentation of object ArrayGet instructions + // does not support the HIntermediateAddress instruction. + DCHECK(!((type == Primitive::kPrimNot) && + instruction->GetArray()->IsIntermediateAddress() && + kEmitCompilerReadBarrier)); + if (type == Primitive::kPrimNot && kEmitCompilerReadBarrier && kUseBakerReadBarrier) { // Object ArrayGet with Baker's read barrier case. Register temp = temps.AcquireW(); - // The read barrier instrumentation does not support the HIntermediateAddress instruction yet. - DCHECK(!instruction->GetArray()->IsIntermediateAddress()); // Note that a potential implicit null check is handled in the // CodeGeneratorARM64::GenerateArrayLoadWithBakerReadBarrier call. codegen_->GenerateArrayLoadWithBakerReadBarrier( @@ -2109,9 +2115,6 @@ void InstructionCodeGeneratorARM64::VisitArrayGet(HArrayGet* instruction) { } else { Register temp = temps.AcquireSameSizeAs(obj); if (instruction->GetArray()->IsIntermediateAddress()) { - // The read barrier instrumentation does not support the - // HIntermediateAddress instruction yet. - DCHECK(!kEmitCompilerReadBarrier); // We do not need to compute the intermediate address from the array: the // input instruction has done it already. See the comment in // `TryExtractArrayAccessAddress()`. @@ -2201,9 +2204,6 @@ void InstructionCodeGeneratorARM64::VisitArraySet(HArraySet* instruction) { UseScratchRegisterScope temps(masm); Register temp = temps.AcquireSameSizeAs(array); if (instruction->GetArray()->IsIntermediateAddress()) { - // The read barrier instrumentation does not support the - // HIntermediateAddress instruction yet. - DCHECK(!kEmitCompilerReadBarrier); // We do not need to compute the intermediate address from the array: the // input instruction has done it already. See the comment in // `TryExtractArrayAccessAddress()`. @@ -2223,7 +2223,6 @@ void InstructionCodeGeneratorARM64::VisitArraySet(HArraySet* instruction) { codegen_->Store(value_type, value, destination); codegen_->MaybeRecordImplicitNullCheck(instruction); } else { - DCHECK(needs_write_barrier); DCHECK(!instruction->GetArray()->IsIntermediateAddress()); vixl::aarch64::Label done; SlowPathCodeARM64* slow_path = nullptr; diff --git a/compiler/optimizing/dead_code_elimination.h b/compiler/optimizing/dead_code_elimination.h index 0ce0ec1402..58e700deba 100644 --- a/compiler/optimizing/dead_code_elimination.h +++ b/compiler/optimizing/dead_code_elimination.h @@ -31,13 +31,11 @@ class HDeadCodeElimination : public HOptimization { public: HDeadCodeElimination(HGraph* graph, OptimizingCompilerStats* stats = nullptr, - const char* name = kInitialDeadCodeEliminationPassName) + const char* name = kDeadCodeEliminationPassName) : HOptimization(graph, name, stats) {} void Run() OVERRIDE; - - static constexpr const char* kInitialDeadCodeEliminationPassName = "dead_code_elimination"; - static constexpr const char* kFinalDeadCodeEliminationPassName = "dead_code_elimination_final"; + static constexpr const char* kDeadCodeEliminationPassName = "dead_code_elimination"; private: void MaybeRecordDeadBlock(HBasicBlock* block); diff --git a/compiler/optimizing/dex_cache_array_fixups_arm.h b/compiler/optimizing/dex_cache_array_fixups_arm.h index 015f910328..9142e29eff 100644 --- a/compiler/optimizing/dex_cache_array_fixups_arm.h +++ b/compiler/optimizing/dex_cache_array_fixups_arm.h @@ -26,7 +26,9 @@ namespace arm { class DexCacheArrayFixups : public HOptimization { public: DexCacheArrayFixups(HGraph* graph, OptimizingCompilerStats* stats) - : HOptimization(graph, "dex_cache_array_fixups_arm", stats) {} + : HOptimization(graph, kDexCacheArrayFixupsArmPassName, stats) {} + + static constexpr const char* kDexCacheArrayFixupsArmPassName = "dex_cache_array_fixups_arm"; void Run() OVERRIDE; }; diff --git a/compiler/optimizing/dex_cache_array_fixups_mips.h b/compiler/optimizing/dex_cache_array_fixups_mips.h index 21056e130a..861a199d6c 100644 --- a/compiler/optimizing/dex_cache_array_fixups_mips.h +++ b/compiler/optimizing/dex_cache_array_fixups_mips.h @@ -29,9 +29,11 @@ namespace mips { class DexCacheArrayFixups : public HOptimization { public: DexCacheArrayFixups(HGraph* graph, CodeGenerator* codegen, OptimizingCompilerStats* stats) - : HOptimization(graph, "dex_cache_array_fixups_mips", stats), + : HOptimization(graph, kDexCacheArrayFixupsMipsPassName, stats), codegen_(codegen) {} + static constexpr const char* kDexCacheArrayFixupsMipsPassName = "dex_cache_array_fixups_mips"; + void Run() OVERRIDE; private: diff --git a/compiler/optimizing/induction_var_analysis.h b/compiler/optimizing/induction_var_analysis.h index 7c74816c26..cd4c830645 100644 --- a/compiler/optimizing/induction_var_analysis.h +++ b/compiler/optimizing/induction_var_analysis.h @@ -39,9 +39,9 @@ class HInductionVarAnalysis : public HOptimization { void Run() OVERRIDE; - private: static constexpr const char* kInductionPassName = "induction_var_analysis"; + private: struct NodeInfo { explicit NodeInfo(uint32_t d) : depth(d), done(false) {} uint32_t depth; diff --git a/compiler/optimizing/instruction_simplifier_arm.h b/compiler/optimizing/instruction_simplifier_arm.h index 3d297dacc0..782110c40a 100644 --- a/compiler/optimizing/instruction_simplifier_arm.h +++ b/compiler/optimizing/instruction_simplifier_arm.h @@ -48,7 +48,9 @@ class InstructionSimplifierArmVisitor : public HGraphVisitor { class InstructionSimplifierArm : public HOptimization { public: InstructionSimplifierArm(HGraph* graph, OptimizingCompilerStats* stats) - : HOptimization(graph, "instruction_simplifier_arm", stats) {} + : HOptimization(graph, kInstructionSimplifierArmPassName, stats) {} + + static constexpr const char* kInstructionSimplifierArmPassName = "instruction_simplifier_arm"; void Run() OVERRIDE { InstructionSimplifierArmVisitor visitor(graph_, stats_); diff --git a/compiler/optimizing/instruction_simplifier_arm64.h b/compiler/optimizing/instruction_simplifier_arm64.h index 28648b3bea..f71684efe9 100644 --- a/compiler/optimizing/instruction_simplifier_arm64.h +++ b/compiler/optimizing/instruction_simplifier_arm64.h @@ -82,8 +82,9 @@ class InstructionSimplifierArm64Visitor : public HGraphVisitor { class InstructionSimplifierArm64 : public HOptimization { public: InstructionSimplifierArm64(HGraph* graph, OptimizingCompilerStats* stats) - : HOptimization(graph, "instruction_simplifier_arm64", stats) {} - + : HOptimization(graph, kInstructionSimplifierArm64PassName, stats) {} + static constexpr const char* kInstructionSimplifierArm64PassName + = "instruction_simplifier_arm64"; void Run() OVERRIDE { InstructionSimplifierArm64Visitor visitor(graph_, stats_); visitor.VisitReversePostOrder(); diff --git a/compiler/optimizing/instruction_simplifier_shared.cc b/compiler/optimizing/instruction_simplifier_shared.cc index 8f7778fe68..6632cd9969 100644 --- a/compiler/optimizing/instruction_simplifier_shared.cc +++ b/compiler/optimizing/instruction_simplifier_shared.cc @@ -231,15 +231,6 @@ bool TryExtractArrayAccessAddress(HInstruction* access, HInstruction* array, HInstruction* index, size_t data_offset) { - if (kEmitCompilerReadBarrier) { - // The read barrier instrumentation does not support the - // HIntermediateAddress instruction yet. - // - // TODO: Handle this case properly in the ARM64 and ARM code generator and - // re-enable this optimization; otherwise, remove this TODO. - // b/26601270 - return false; - } if (index->IsConstant() || (index->IsBoundsCheck() && index->AsBoundsCheck()->GetIndex()->IsConstant())) { // When the index is a constant all the addressing can be fitted in the @@ -251,6 +242,13 @@ bool TryExtractArrayAccessAddress(HInstruction* access, // The access may require a runtime call or the original array pointer. return false; } + if (kEmitCompilerReadBarrier && + access->IsArrayGet() && + access->AsArrayGet()->GetType() == Primitive::kPrimNot) { + // For object arrays, the read barrier instrumentation requires + // the original array pointer. + return false; + } // Proceed to extract the base address computation. HGraph* graph = access->GetBlock()->GetGraph(); diff --git a/compiler/optimizing/optimization.h b/compiler/optimizing/optimization.h index 2f59d4cd5b..0819fb01ac 100644 --- a/compiler/optimizing/optimization.h +++ b/compiler/optimizing/optimization.h @@ -37,7 +37,10 @@ class HOptimization : public ArenaObject<kArenaAllocOptimization> { virtual ~HOptimization() {} - // Return the name of the pass. + // Return the name of the pass. Pass names for a single HOptimization should be of form + // <optimization_name> or <optimization_name>$<pass_name> for common <optimization_name> prefix. + // Example: 'instruction_simplifier', 'instruction_simplifier$after_bce', + // 'instruction_simplifier$before_codegen'. const char* GetPassName() const { return pass_name_; } // Perform the analysis itself. diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index d5b0d77fe5..f7c82d1987 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -95,6 +95,8 @@ namespace art { static constexpr size_t kArenaAllocatorMemoryReportThreshold = 8 * MB; +static constexpr const char* kPassNameSeparator = "$"; + /** * Used by the code generator, to allocate the code in a vector. */ @@ -266,7 +268,7 @@ class PassScope : public ValueObject { class OptimizingCompiler FINAL : public Compiler { public: explicit OptimizingCompiler(CompilerDriver* driver); - ~OptimizingCompiler(); + ~OptimizingCompiler() OVERRIDE; bool CanCompileMethod(uint32_t method_idx, const DexFile& dex_file) const OVERRIDE; @@ -305,17 +307,17 @@ class OptimizingCompiler FINAL : public Compiler { OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_); - protected: - virtual void RunOptimizations(HGraph* graph, - CodeGenerator* codegen, - CompilerDriver* driver, - const DexCompilationUnit& dex_compilation_unit, - PassObserver* pass_observer, - StackHandleScopeCollection* handles) const; + private: + void RunOptimizations(HGraph* graph, + CodeGenerator* codegen, + CompilerDriver* driver, + const DexCompilationUnit& dex_compilation_unit, + PassObserver* pass_observer, + StackHandleScopeCollection* handles) const; - virtual void RunOptimizations(HOptimization* optimizations[], - size_t length, - PassObserver* pass_observer) const; + void RunOptimizations(HOptimization* optimizations[], + size_t length, + PassObserver* pass_observer) const; private: // Create a 'CompiledMethod' for an optimized graph. @@ -420,6 +422,117 @@ static bool InstructionSetSupportsReadBarrier(InstructionSet instruction_set) { || instruction_set == kX86_64; } +static HOptimization* BuildOptimization( + const std::string& opt_name, + ArenaAllocator* arena, + HGraph* graph, + OptimizingCompilerStats* stats, + CodeGenerator* codegen, + CompilerDriver* driver, + const DexCompilationUnit& dex_compilation_unit, + StackHandleScopeCollection* handles, + SideEffectsAnalysis* most_recent_side_effects, + HInductionVarAnalysis* most_recent_induction) { + if (opt_name == arm::InstructionSimplifierArm::kInstructionSimplifierArmPassName) { + return new (arena) arm::InstructionSimplifierArm(graph, stats); + } else if (opt_name == arm64::InstructionSimplifierArm64::kInstructionSimplifierArm64PassName) { + return new (arena) arm64::InstructionSimplifierArm64(graph, stats); + } else if (opt_name == BoundsCheckElimination::kBoundsCheckEliminationPassName) { + CHECK(most_recent_side_effects != nullptr && most_recent_induction != nullptr); + return new (arena) BoundsCheckElimination(graph, + *most_recent_side_effects, + most_recent_induction); + } else if (opt_name == GVNOptimization::kGlobalValueNumberingPassName) { + CHECK(most_recent_side_effects != nullptr); + return new (arena) GVNOptimization(graph, *most_recent_side_effects); + } else if (opt_name == HConstantFolding::kConstantFoldingPassName) { + return new (arena) HConstantFolding(graph); + } else if (opt_name == HDeadCodeElimination::kDeadCodeEliminationPassName) { + return new (arena) HDeadCodeElimination(graph, stats); + } else if (opt_name == HInliner::kInlinerPassName) { + size_t number_of_dex_registers = dex_compilation_unit.GetCodeItem()->registers_size_; + return new (arena) HInliner(graph, // outer_graph + graph, // outermost_graph + codegen, + dex_compilation_unit, // outer_compilation_unit + dex_compilation_unit, // outermost_compilation_unit + driver, + handles, + stats, + number_of_dex_registers, + /* depth */ 0); + } else if (opt_name == HSharpening::kSharpeningPassName) { + return new (arena) HSharpening(graph, codegen, dex_compilation_unit, driver); + } else if (opt_name == HSelectGenerator::kSelectGeneratorPassName) { + return new (arena) HSelectGenerator(graph, stats); + } else if (opt_name == HInductionVarAnalysis::kInductionPassName) { + return new (arena) HInductionVarAnalysis(graph); + } else if (opt_name == InstructionSimplifier::kInstructionSimplifierPassName) { + return new (arena) InstructionSimplifier(graph, stats); + } else if (opt_name == IntrinsicsRecognizer::kIntrinsicsRecognizerPassName) { + return new (arena) IntrinsicsRecognizer(graph, driver, stats); + } else if (opt_name == LICM::kLoopInvariantCodeMotionPassName) { + CHECK(most_recent_side_effects != nullptr); + return new (arena) LICM(graph, *most_recent_side_effects, stats); + } else if (opt_name == LoadStoreElimination::kLoadStoreEliminationPassName) { + CHECK(most_recent_side_effects != nullptr); + return new (arena) LoadStoreElimination(graph, *most_recent_side_effects); + } else if (opt_name == mips::DexCacheArrayFixups::kDexCacheArrayFixupsMipsPassName) { + return new (arena) mips::DexCacheArrayFixups(graph, codegen, stats); + } else if (opt_name == mips::PcRelativeFixups::kPcRelativeFixupsMipsPassName) { + return new (arena) mips::PcRelativeFixups(graph, codegen, stats); + } else if (opt_name == SideEffectsAnalysis::kSideEffectsAnalysisPassName) { + return new (arena) SideEffectsAnalysis(graph); + } else if (opt_name == x86::PcRelativeFixups::kPcRelativeFixupsX86PassName) { + return new (arena) x86::PcRelativeFixups(graph, codegen, stats); + } else if (opt_name == x86::X86MemoryOperandGeneration::kX86MemoryOperandGenerationPassName) { + return new (arena) x86::X86MemoryOperandGeneration(graph, codegen, stats); + } + return nullptr; +} + +static ArenaVector<HOptimization*> BuildOptimizations( + const std::vector<std::string>& pass_names, + ArenaAllocator* arena, + HGraph* graph, + OptimizingCompilerStats* stats, + CodeGenerator* codegen, + CompilerDriver* driver, + const DexCompilationUnit& dex_compilation_unit, + StackHandleScopeCollection* handles) { + // Few HOptimizations constructors require SideEffectsAnalysis or HInductionVarAnalysis + // instances. This method assumes that each of them expects the nearest instance preceeding it + // in the pass name list. + SideEffectsAnalysis* most_recent_side_effects = nullptr; + HInductionVarAnalysis* most_recent_induction = nullptr; + ArenaVector<HOptimization*> ret(arena->Adapter()); + for (std::string pass_name : pass_names) { + size_t pos = pass_name.find(kPassNameSeparator); // Strip suffix to get base pass name. + std::string opt_name = pos == std::string::npos ? pass_name : pass_name.substr(0, pos); + + HOptimization* opt = BuildOptimization( + opt_name, + arena, + graph, + stats, + codegen, + driver, + dex_compilation_unit, + handles, + most_recent_side_effects, + most_recent_induction); + CHECK(opt != nullptr) << "Couldn't build optimization: \"" << pass_name << "\""; + ret.push_back(opt); + + if (opt_name == SideEffectsAnalysis::kSideEffectsAnalysisPassName) { + most_recent_side_effects = down_cast<SideEffectsAnalysis*>(opt); + } else if (opt_name == HInductionVarAnalysis::kInductionPassName) { + most_recent_induction = down_cast<HInductionVarAnalysis*>(opt); + } + } + return ret; +} + void OptimizingCompiler::RunOptimizations(HOptimization* optimizations[], size_t length, PassObserver* pass_observer) const { @@ -444,11 +557,11 @@ void OptimizingCompiler::MaybeRunInliner(HGraph* graph, } size_t number_of_dex_registers = dex_compilation_unit.GetCodeItem()->registers_size_; HInliner* inliner = new (graph->GetArena()) HInliner( - graph, - graph, + graph, // outer_graph + graph, // outermost_graph codegen, - dex_compilation_unit, - dex_compilation_unit, + dex_compilation_unit, // outer_compilation_unit + dex_compilation_unit, // outermost_compilation_unit driver, handles, stats, @@ -473,7 +586,7 @@ void OptimizingCompiler::RunArchOptimizations(InstructionSet instruction_set, arm::InstructionSimplifierArm* simplifier = new (arena) arm::InstructionSimplifierArm(graph, stats); SideEffectsAnalysis* side_effects = new (arena) SideEffectsAnalysis(graph); - GVNOptimization* gvn = new (arena) GVNOptimization(graph, *side_effects, "GVN_after_arch"); + GVNOptimization* gvn = new (arena) GVNOptimization(graph, *side_effects, "GVN$after_arch"); HOptimization* arm_optimizations[] = { simplifier, side_effects, @@ -489,7 +602,7 @@ void OptimizingCompiler::RunArchOptimizations(InstructionSet instruction_set, arm64::InstructionSimplifierArm64* simplifier = new (arena) arm64::InstructionSimplifierArm64(graph, stats); SideEffectsAnalysis* side_effects = new (arena) SideEffectsAnalysis(graph); - GVNOptimization* gvn = new (arena) GVNOptimization(graph, *side_effects, "GVN_after_arch"); + GVNOptimization* gvn = new (arena) GVNOptimization(graph, *side_effects, "GVN$after_arch"); HOptimization* arm64_optimizations[] = { simplifier, side_effects, @@ -518,7 +631,7 @@ void OptimizingCompiler::RunArchOptimizations(InstructionSet instruction_set, x86::PcRelativeFixups* pc_relative_fixups = new (arena) x86::PcRelativeFixups(graph, codegen, stats); x86::X86MemoryOperandGeneration* memory_gen = - new(arena) x86::X86MemoryOperandGeneration(graph, stats, codegen); + new (arena) x86::X86MemoryOperandGeneration(graph, codegen, stats); HOptimization* x86_optimizations[] = { pc_relative_fixups, memory_gen @@ -530,7 +643,7 @@ void OptimizingCompiler::RunArchOptimizations(InstructionSet instruction_set, #ifdef ART_ENABLE_CODEGEN_x86_64 case kX86_64: { x86::X86MemoryOperandGeneration* memory_gen = - new(arena) x86::X86MemoryOperandGeneration(graph, stats, codegen); + new (arena) x86::X86MemoryOperandGeneration(graph, codegen, stats); HOptimization* x86_64_optimizations[] = { memory_gen }; @@ -546,7 +659,8 @@ void OptimizingCompiler::RunArchOptimizations(InstructionSet instruction_set, NO_INLINE // Avoid increasing caller's frame size by large stack-allocated objects. static void AllocateRegisters(HGraph* graph, CodeGenerator* codegen, - PassObserver* pass_observer) { + PassObserver* pass_observer, + RegisterAllocator::Strategy strategy) { { PassScope scope(PrepareForRegisterAllocation::kPrepareForRegisterAllocationPassName, pass_observer); @@ -559,7 +673,7 @@ static void AllocateRegisters(HGraph* graph, } { PassScope scope(RegisterAllocator::kRegisterAllocatorPassName, pass_observer); - RegisterAllocator::Create(graph->GetArena(), codegen, liveness)->AllocateRegisters(); + RegisterAllocator::Create(graph->GetArena(), codegen, liveness, strategy)->AllocateRegisters(); } } @@ -571,15 +685,30 @@ void OptimizingCompiler::RunOptimizations(HGraph* graph, StackHandleScopeCollection* handles) const { OptimizingCompilerStats* stats = compilation_stats_.get(); ArenaAllocator* arena = graph->GetArena(); + if (driver->GetCompilerOptions().GetPassesToRun() != nullptr) { + ArenaVector<HOptimization*> optimizations = BuildOptimizations( + *driver->GetCompilerOptions().GetPassesToRun(), + arena, + graph, + stats, + codegen, + driver, + dex_compilation_unit, + handles); + RunOptimizations(&optimizations[0], optimizations.size(), pass_observer); + return; + } + HDeadCodeElimination* dce1 = new (arena) HDeadCodeElimination( - graph, stats, HDeadCodeElimination::kInitialDeadCodeEliminationPassName); + graph, stats, "dead_code_elimination$initial"); HDeadCodeElimination* dce2 = new (arena) HDeadCodeElimination( - graph, stats, HDeadCodeElimination::kFinalDeadCodeEliminationPassName); + graph, stats, "dead_code_elimination$final"); HConstantFolding* fold1 = new (arena) HConstantFolding(graph); InstructionSimplifier* simplify1 = new (arena) InstructionSimplifier(graph, stats); HSelectGenerator* select_generator = new (arena) HSelectGenerator(graph, stats); - HConstantFolding* fold2 = new (arena) HConstantFolding(graph, "constant_folding_after_inlining"); - HConstantFolding* fold3 = new (arena) HConstantFolding(graph, "constant_folding_after_bce"); + HConstantFolding* fold2 = new (arena) HConstantFolding( + graph, "constant_folding$after_inlining"); + HConstantFolding* fold3 = new (arena) HConstantFolding(graph, "constant_folding$after_bce"); SideEffectsAnalysis* side_effects = new (arena) SideEffectsAnalysis(graph); GVNOptimization* gvn = new (arena) GVNOptimization(graph, *side_effects); LICM* licm = new (arena) LICM(graph, *side_effects, stats); @@ -588,9 +717,9 @@ void OptimizingCompiler::RunOptimizations(HGraph* graph, BoundsCheckElimination* bce = new (arena) BoundsCheckElimination(graph, *side_effects, induction); HSharpening* sharpening = new (arena) HSharpening(graph, codegen, dex_compilation_unit, driver); InstructionSimplifier* simplify2 = new (arena) InstructionSimplifier( - graph, stats, "instruction_simplifier_after_bce"); + graph, stats, "instruction_simplifier$after_bce"); InstructionSimplifier* simplify3 = new (arena) InstructionSimplifier( - graph, stats, "instruction_simplifier_before_codegen"); + graph, stats, "instruction_simplifier$before_codegen"); IntrinsicsRecognizer* intrinsics = new (arena) IntrinsicsRecognizer(graph, driver, stats); HOptimization* optimizations1[] = { @@ -626,7 +755,6 @@ void OptimizingCompiler::RunOptimizations(HGraph* graph, RunOptimizations(optimizations2, arraysize(optimizations2), pass_observer); RunArchOptimizations(driver->GetInstructionSet(), graph, codegen, pass_observer); - AllocateRegisters(graph, codegen, pass_observer); } static ArenaVector<LinkerPatch> EmitAndSortLinkerPatches(CodeGenerator* codegen) { @@ -841,6 +969,10 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* arena, &pass_observer, &handles); + RegisterAllocator::Strategy regalloc_strategy = + compiler_options.GetRegisterAllocationStrategy(); + AllocateRegisters(graph, codegen.get(), &pass_observer, regalloc_strategy); + codegen->Compile(code_allocator); pass_observer.DumpDisassembly(); } diff --git a/compiler/optimizing/pc_relative_fixups_mips.h b/compiler/optimizing/pc_relative_fixups_mips.h index 1e8b071bb3..5a7397bf9d 100644 --- a/compiler/optimizing/pc_relative_fixups_mips.h +++ b/compiler/optimizing/pc_relative_fixups_mips.h @@ -32,6 +32,8 @@ class PcRelativeFixups : public HOptimization { : HOptimization(graph, "pc_relative_fixups_mips", stats), codegen_(codegen) {} + static constexpr const char* kPcRelativeFixupsMipsPassName = "pc_relative_fixups_mips"; + void Run() OVERRIDE; private: diff --git a/compiler/optimizing/pc_relative_fixups_x86.h b/compiler/optimizing/pc_relative_fixups_x86.h index 03de2fcece..72fa71ea94 100644 --- a/compiler/optimizing/pc_relative_fixups_x86.h +++ b/compiler/optimizing/pc_relative_fixups_x86.h @@ -29,9 +29,11 @@ namespace x86 { class PcRelativeFixups : public HOptimization { public: PcRelativeFixups(HGraph* graph, CodeGenerator* codegen, OptimizingCompilerStats* stats) - : HOptimization(graph, "pc_relative_fixups_x86", stats), + : HOptimization(graph, kPcRelativeFixupsX86PassName, stats), codegen_(codegen) {} + static constexpr const char* kPcRelativeFixupsX86PassName = "pc_relative_fixups_x86"; + void Run() OVERRIDE; private: diff --git a/compiler/optimizing/x86_memory_gen.cc b/compiler/optimizing/x86_memory_gen.cc index 195159f61b..8aa315a7e3 100644 --- a/compiler/optimizing/x86_memory_gen.cc +++ b/compiler/optimizing/x86_memory_gen.cc @@ -69,8 +69,8 @@ class MemoryOperandVisitor : public HGraphVisitor { }; X86MemoryOperandGeneration::X86MemoryOperandGeneration(HGraph* graph, - OptimizingCompilerStats* stats, - CodeGenerator* codegen) + CodeGenerator* codegen, + OptimizingCompilerStats* stats) : HOptimization(graph, kX86MemoryOperandGenerationPassName, stats), do_implicit_null_checks_(codegen->GetCompilerOptions().GetImplicitNullChecks()) { } diff --git a/compiler/optimizing/x86_memory_gen.h b/compiler/optimizing/x86_memory_gen.h index 7e886819bb..5f15d9f1e6 100644 --- a/compiler/optimizing/x86_memory_gen.h +++ b/compiler/optimizing/x86_memory_gen.h @@ -28,8 +28,8 @@ namespace x86 { class X86MemoryOperandGeneration : public HOptimization { public: X86MemoryOperandGeneration(HGraph* graph, - OptimizingCompilerStats* stats, - CodeGenerator* codegen); + CodeGenerator* codegen, + OptimizingCompilerStats* stats); void Run() OVERRIDE; |