diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/Android.bp | 24 | ||||
| -rw-r--r-- | compiler/driver/compiler_options.cc | 2 | ||||
| -rw-r--r-- | compiler/driver/compiler_options.h | 16 | ||||
| -rw-r--r-- | compiler/jit/jit_compiler.cc | 11 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 29 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_x86.h | 1 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 41 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_x86_64.h | 1 | ||||
| -rw-r--r-- | compiler/optimizing/inliner.cc | 24 | ||||
| -rw-r--r-- | compiler/optimizing/optimizing_compiler.cc | 21 | ||||
| -rw-r--r-- | compiler/optimizing/optimizing_compiler.h | 7 |
11 files changed, 114 insertions, 63 deletions
diff --git a/compiler/Android.bp b/compiler/Android.bp index 30a65b280a..0d92b05593 100644 --- a/compiler/Android.bp +++ b/compiler/Android.bp @@ -183,7 +183,6 @@ art_cc_defaults { shared_libs: [ "libbase", "libcutils", // for atrace. - "liblzma", ], include_dirs: ["art/disassembler"], header_libs: [ @@ -199,7 +198,6 @@ cc_defaults { static_libs: [ "libbase", "libcutils", - "liblzma", ], } @@ -233,12 +231,12 @@ art_cc_library { // VIXL assembly support for ARM targets. static: { whole_static_libs: [ - "libvixl-arm", + "libvixl", ], }, shared: { shared_libs: [ - "libvixl-arm", + "libvixl", ], }, }, @@ -246,12 +244,12 @@ art_cc_library { // VIXL assembly support for ARM64 targets. static: { whole_static_libs: [ - "libvixl-arm64", + "libvixl", ], }, shared: { shared_libs: [ - "libvixl-arm64", + "libvixl", ], }, }, @@ -295,12 +293,12 @@ art_cc_library { // VIXL assembly support for ARM targets. static: { whole_static_libs: [ - "libvixld-arm", + "libvixld", ], }, shared: { shared_libs: [ - "libvixld-arm", + "libvixld", ], }, }, @@ -308,12 +306,12 @@ art_cc_library { // VIXL assembly support for ARM64 targets. static: { whole_static_libs: [ - "libvixld-arm64", + "libvixld", ], }, shared: { shared_libs: [ - "libvixld-arm64", + "libvixld", ], }, }, @@ -454,8 +452,7 @@ art_cc_test { "libprofiled", "libartd-compiler", "libartd-simulator-container", - "libvixld-arm", - "libvixld-arm64", + "libvixld", "libbacktrace", "libnativeloader", @@ -512,7 +509,6 @@ art_cc_test { }, shared_libs: [ "libartd-compiler", - "libvixld-arm", - "libvixld-arm64", + "libvixld", ], } diff --git a/compiler/driver/compiler_options.cc b/compiler/driver/compiler_options.cc index be8e10e41e..685cde338b 100644 --- a/compiler/driver/compiler_options.cc +++ b/compiler/driver/compiler_options.cc @@ -45,8 +45,8 @@ CompilerOptions::CompilerOptions() dex_files_for_oat_file_(), image_classes_(), boot_image_(false), - core_image_(false), app_image_(false), + compiling_with_core_image_(false), baseline_(false), debuggable_(false), generate_debug_info_(kDefaultGenerateDebugInfo), diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h index 77f84820e5..2f4e5428ea 100644 --- a/compiler/driver/compiler_options.h +++ b/compiler/driver/compiler_options.h @@ -198,13 +198,6 @@ class CompilerOptions final { return baseline_; } - // Are we compiling a core image (small boot image only used for ART testing)? - bool IsCoreImage() const { - // Ensure that `core_image_` => `boot_image_`. - DCHECK(!core_image_ || boot_image_); - return core_image_; - } - // Are we compiling an app image? bool IsAppImage() const { return app_image_; @@ -214,6 +207,13 @@ class CompilerOptions final { app_image_ = false; } + // Returns whether we are compiling against a "core" image, which + // is an indicative we are running tests. The compiler will use that + // information for checking invariants. + bool CompilingWithCoreImage() const { + return compiling_with_core_image_; + } + // Should the code be compiled as position independent? bool GetCompilePic() const { return compile_pic_; @@ -357,8 +357,8 @@ class CompilerOptions final { HashSet<std::string> image_classes_; bool boot_image_; - bool core_image_; bool app_image_; + bool compiling_with_core_image_; bool baseline_; bool debuggable_; bool generate_debug_info_; diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc index f22f61fa21..bb35065921 100644 --- a/compiler/jit/jit_compiler.cc +++ b/compiler/jit/jit_compiler.cc @@ -90,10 +90,11 @@ JitCompiler::JitCompiler() { // Special case max code units for inlining, whose default is "unset" (implictly // meaning no limit). Do this before parsing the actual passed options. compiler_options_->SetInlineMaxCodeUnits(CompilerOptions::kDefaultInlineMaxCodeUnits); + Runtime* runtime = Runtime::Current(); { std::string error_msg; - if (!compiler_options_->ParseCompilerOptions(Runtime::Current()->GetCompilerOptions(), - true /* ignore_unrecognized */, + if (!compiler_options_->ParseCompilerOptions(runtime->GetCompilerOptions(), + /*ignore_unrecognized=*/ true, &error_msg)) { LOG(FATAL) << error_msg; UNREACHABLE(); @@ -103,7 +104,7 @@ JitCompiler::JitCompiler() { compiler_options_->SetNonPic(); // Set debuggability based on the runtime value. - compiler_options_->SetDebuggable(Runtime::Current()->IsJavaDebuggable()); + compiler_options_->SetDebuggable(runtime->IsJavaDebuggable()); const InstructionSet instruction_set = compiler_options_->GetInstructionSet(); if (kRuntimeISA == InstructionSet::kArm) { @@ -112,7 +113,7 @@ JitCompiler::JitCompiler() { DCHECK_EQ(instruction_set, kRuntimeISA); } std::unique_ptr<const InstructionSetFeatures> instruction_set_features; - for (const StringPiece option : Runtime::Current()->GetCompilerOptions()) { + for (const StringPiece option : runtime->GetCompilerOptions()) { VLOG(compiler) << "JIT compiler option " << option; std::string error_msg; if (option.starts_with("--instruction-set-variant=")) { @@ -144,6 +145,8 @@ JitCompiler::JitCompiler() { instruction_set_features = InstructionSetFeatures::FromCppDefines(); } compiler_options_->instruction_set_features_ = std::move(instruction_set_features); + compiler_options_->compiling_with_core_image_ = + CompilerDriver::IsCoreImageFilename(runtime->GetImageLocation()); compiler_driver_.reset(new CompilerDriver( compiler_options_.get(), diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 7dcf28952d..fba4da63cc 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -3497,6 +3497,27 @@ void InstructionCodeGeneratorX86::DivRemOneOrMinusOne(HBinaryOperation* instruct } } +void InstructionCodeGeneratorX86::RemByPowerOfTwo(HRem* instruction) { + LocationSummary* locations = instruction->GetLocations(); + Location second = locations->InAt(1); + + Register out = locations->Out().AsRegister<Register>(); + Register numerator = locations->InAt(0).AsRegister<Register>(); + + int32_t imm = Int64FromConstant(second.GetConstant()); + DCHECK(IsPowerOfTwo(AbsOrMin(imm))); + uint32_t abs_imm = static_cast<uint32_t>(AbsOrMin(imm)); + + Register tmp = locations->GetTemp(0).AsRegister<Register>(); + NearLabel done; + __ movl(out, numerator); + __ andl(out, Immediate(abs_imm-1)); + __ j(Condition::kZero, &done); + __ leal(tmp, Address(out, static_cast<int32_t>(~(abs_imm-1)))); + __ testl(numerator, numerator); + __ cmovl(Condition::kLess, out, tmp); + __ Bind(&done); +} void InstructionCodeGeneratorX86::DivByPowerOfTwo(HDiv* instruction) { LocationSummary* locations = instruction->GetLocations(); @@ -3610,8 +3631,12 @@ void InstructionCodeGeneratorX86::GenerateDivRemIntegral(HBinaryOperation* instr // Do not generate anything for 0. DivZeroCheck would forbid any generated code. } else if (imm == 1 || imm == -1) { DivRemOneOrMinusOne(instruction); - } else if (is_div && IsPowerOfTwo(AbsOrMin(imm))) { - DivByPowerOfTwo(instruction->AsDiv()); + } else if (IsPowerOfTwo(AbsOrMin(imm))) { + if (is_div) { + DivByPowerOfTwo(instruction->AsDiv()); + } else { + RemByPowerOfTwo(instruction->AsRem()); + } } else { DCHECK(imm <= -2 || imm >= 2); GenerateDivRemWithAnyConstant(instruction); diff --git a/compiler/optimizing/code_generator_x86.h b/compiler/optimizing/code_generator_x86.h index 1e49403402..deeef888e2 100644 --- a/compiler/optimizing/code_generator_x86.h +++ b/compiler/optimizing/code_generator_x86.h @@ -218,6 +218,7 @@ class InstructionCodeGeneratorX86 : public InstructionCodeGenerator { void GenerateDivRemIntegral(HBinaryOperation* instruction); void DivRemOneOrMinusOne(HBinaryOperation* instruction); void DivByPowerOfTwo(HDiv* instruction); + void RemByPowerOfTwo(HRem* instruction); void GenerateDivRemWithAnyConstant(HBinaryOperation* instruction); void GenerateRemFP(HRem* rem); void HandleCondition(HCondition* condition); diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index d8253907fc..14cff05f58 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -3560,7 +3560,40 @@ void InstructionCodeGeneratorX86_64::DivRemOneOrMinusOne(HBinaryOperation* instr LOG(FATAL) << "Unexpected type for div by (-)1 " << instruction->GetResultType(); } } +void InstructionCodeGeneratorX86_64::RemByPowerOfTwo(HRem* instruction) { + LocationSummary* locations = instruction->GetLocations(); + Location second = locations->InAt(1); + CpuRegister out = locations->Out().AsRegister<CpuRegister>(); + CpuRegister numerator = locations->InAt(0).AsRegister<CpuRegister>(); + int64_t imm = Int64FromConstant(second.GetConstant()); + DCHECK(IsPowerOfTwo(AbsOrMin(imm))); + uint64_t abs_imm = AbsOrMin(imm); + CpuRegister tmp = locations->GetTemp(0).AsRegister<CpuRegister>(); + if (instruction->GetResultType() == DataType::Type::kInt32) { + NearLabel done; + __ movl(out, numerator); + __ andl(out, Immediate(abs_imm-1)); + __ j(Condition::kZero, &done); + __ leal(tmp, Address(out, static_cast<int32_t>(~(abs_imm-1)))); + __ testl(numerator, numerator); + __ cmov(Condition::kLess, out, tmp, false); + __ Bind(&done); + + } else { + DCHECK_EQ(instruction->GetResultType(), DataType::Type::kInt64); + codegen_->Load64BitValue(tmp, abs_imm - 1); + NearLabel done; + __ movq(out, numerator); + __ andq(out, tmp); + __ j(Condition::kZero, &done); + __ movq(tmp, numerator); + __ sarq(tmp, Immediate(63)); + __ shlq(tmp, Immediate(WhichPowerOf2(abs_imm))); + __ orq(out, tmp); + __ Bind(&done); + } +} void InstructionCodeGeneratorX86_64::DivByPowerOfTwo(HDiv* instruction) { LocationSummary* locations = instruction->GetLocations(); Location second = locations->InAt(1); @@ -3737,8 +3770,12 @@ void InstructionCodeGeneratorX86_64::GenerateDivRemIntegral(HBinaryOperation* in // Do not generate anything. DivZeroCheck would prevent any code to be executed. } else if (imm == 1 || imm == -1) { DivRemOneOrMinusOne(instruction); - } else if (instruction->IsDiv() && IsPowerOfTwo(AbsOrMin(imm))) { - DivByPowerOfTwo(instruction->AsDiv()); + } else if (IsPowerOfTwo(AbsOrMin(imm))) { + if (is_div) { + DivByPowerOfTwo(instruction->AsDiv()); + } else { + RemByPowerOfTwo(instruction->AsRem()); + } } else { DCHECK(imm <= -2 || imm >= 2); GenerateDivRemWithAnyConstant(instruction); diff --git a/compiler/optimizing/code_generator_x86_64.h b/compiler/optimizing/code_generator_x86_64.h index 72c4fd499d..f74e130702 100644 --- a/compiler/optimizing/code_generator_x86_64.h +++ b/compiler/optimizing/code_generator_x86_64.h @@ -215,6 +215,7 @@ class InstructionCodeGeneratorX86_64 : public InstructionCodeGenerator { void GenerateRemFP(HRem* rem); void DivRemOneOrMinusOne(HBinaryOperation* instruction); void DivByPowerOfTwo(HDiv* instruction); + void RemByPowerOfTwo(HRem* instruction); void GenerateDivRemWithAnyConstant(HBinaryOperation* instruction); void GenerateDivRemIntegral(HBinaryOperation* instruction); void HandleCondition(HCondition* condition); diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index c1daf95727..d85bfd5564 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -39,7 +39,6 @@ #include "mirror/object_array-alloc-inl.h" #include "mirror/object_array-inl.h" #include "nodes.h" -#include "optimizing_compiler.h" #include "reference_type_propagation.h" #include "register_allocator_linear_scan.h" #include "scoped_thread_state_change-inl.h" @@ -151,13 +150,13 @@ bool HInliner::Run() { // If we're compiling with a core image (which is only used for // test purposes), honor inlining directives in method names: - // - if a method's name contains the substring "$inline$", ensure - // that this method is actually inlined; // - if a method's name contains the substring "$noinline$", do not - // inline that method. + // inline that method; + // - if a method's name contains the substring "$inline$", ensure + // that this method is actually inlined. // We limit the latter to AOT compilation, as the JIT may or may not inline // depending on the state of classes at runtime. - const bool honor_noinline_directives = IsCompilingWithCoreImage(); + const bool honor_noinline_directives = codegen_->GetCompilerOptions().CompilingWithCoreImage(); const bool honor_inline_directives = honor_noinline_directives && Runtime::Current()->IsAotCompiler(); @@ -1737,6 +1736,21 @@ static inline Handle<T> NewHandleIfDifferent(T* object, return (object != hint.Get()) ? handles->NewHandle(object) : hint; } +static bool CanEncodeInlinedMethodInStackMap(const DexFile& caller_dex_file, ArtMethod* callee) + REQUIRES_SHARED(Locks::mutator_lock_) { + if (!Runtime::Current()->IsAotCompiler()) { + // JIT can always encode methods in stack maps. + return true; + } + if (IsSameDexFile(caller_dex_file, *callee->GetDexFile())) { + return true; + } + // TODO(ngeoffray): Support more AOT cases for inlining: + // - methods in multidex + // - methods in boot image for on-device non-PIC compilation. + return false; +} + bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, ArtMethod* resolved_method, ReferenceTypeInfo receiver_type, diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index c9c1194e5a..fe6abd4999 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -1136,7 +1136,7 @@ CompiledMethod* OptimizingCompiler::Compile(const DexFile::CodeItem* code_item, } if (kIsDebugBuild && - IsCompilingWithCoreImage() && + compiler_driver->GetCompilerOptions().CompilingWithCoreImage() && IsInstructionSetSupported(compiler_driver->GetCompilerOptions().GetInstructionSet())) { // For testing purposes, we put a special marker on method names // that should be compiled with this compiler (when the @@ -1234,30 +1234,11 @@ Compiler* CreateOptimizingCompiler(CompilerDriver* driver) { return new OptimizingCompiler(driver); } -bool IsCompilingWithCoreImage() { - const std::string& image = Runtime::Current()->GetImageLocation(); - return CompilerDriver::IsCoreImageFilename(image); -} - bool EncodeArtMethodInInlineInfo(ArtMethod* method ATTRIBUTE_UNUSED) { // Note: the runtime is null only for unit testing. return Runtime::Current() == nullptr || !Runtime::Current()->IsAotCompiler(); } -bool CanEncodeInlinedMethodInStackMap(const DexFile& caller_dex_file, ArtMethod* callee) { - if (!Runtime::Current()->IsAotCompiler()) { - // JIT can always encode methods in stack maps. - return true; - } - if (IsSameDexFile(caller_dex_file, *callee->GetDexFile())) { - return true; - } - // TODO(ngeoffray): Support more AOT cases for inlining: - // - methods in multidex - // - methods in boot image for on-device non-PIC compilation. - return false; -} - bool OptimizingCompiler::JitCompile(Thread* self, jit::JitCodeCache* code_cache, ArtMethod* method, diff --git a/compiler/optimizing/optimizing_compiler.h b/compiler/optimizing/optimizing_compiler.h index 6ee9c70fdb..f5279e83eb 100644 --- a/compiler/optimizing/optimizing_compiler.h +++ b/compiler/optimizing/optimizing_compiler.h @@ -29,14 +29,7 @@ class DexFile; Compiler* CreateOptimizingCompiler(CompilerDriver* driver); -// Returns whether we are compiling against a "core" image, which -// is an indicative we are running tests. The compiler will use that -// information for checking invariants. -bool IsCompilingWithCoreImage(); - bool EncodeArtMethodInInlineInfo(ArtMethod* method); -bool CanEncodeInlinedMethodInStackMap(const DexFile& caller_dex_file, ArtMethod* callee) - REQUIRES_SHARED(Locks::mutator_lock_); } // namespace art |