diff options
author | 2019-12-08 22:07:08 +0000 | |
---|---|---|
committer | 2019-12-17 09:48:00 +0000 | |
commit | 57cacb720e6f995aa1a42df6e2e6470a9ec57261 (patch) | |
tree | bb73a113c94bc397cd7c99a4c64e033bf29b9803 /compiler/optimizing | |
parent | 013d1ee96b928f3bda9031e94d4a69f827133ce6 (diff) |
Refactor OSR related code to prepare for "true" OSR.
- Make the compiler restore all callee-save registers.
- Make the compiler return any value in a core register: this simplifies
the current stub, and will also avoid having to look at the return
type (and reading the shorty) when returning to an nterp frame.
- Add OsrData and offsets of its members to be used by nterp.
Test: test.py
Bug: 27094810
Change-Id: Ifa4f4877ab8b1f0c6a96feccea30c909942eb2fa
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/code_generator.cc | 14 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm64.cc | 16 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm_vixl.cc | 16 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 59 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 53 |
5 files changed, 114 insertions, 44 deletions
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index 8406ef5504..a94514c070 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -1011,6 +1011,20 @@ CodeGenerator::CodeGenerator(HGraph* graph, is_leaf_(true), requires_current_method_(false), code_generation_data_() { + if (GetGraph()->IsCompilingOsr()) { + // Make OSR methods have all registers spilled, this simplifies the logic of + // jumping to the compiled code directly. + for (size_t i = 0; i < number_of_core_registers_; ++i) { + if (IsCoreCalleeSaveRegister(i)) { + AddAllocatedRegister(Location::RegisterLocation(i)); + } + } + for (size_t i = 0; i < number_of_fpu_registers_; ++i) { + if (IsFloatingPointCalleeSaveRegister(i)) { + AddAllocatedRegister(Location::FpuRegisterLocation(i)); + } + } + } } CodeGenerator::~CodeGenerator() {} diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index d3ce2db214..64ec987294 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -5530,7 +5530,21 @@ void LocationsBuilderARM64::VisitReturn(HReturn* instruction) { locations->SetInAt(0, ARM64ReturnLocation(return_type)); } -void InstructionCodeGeneratorARM64::VisitReturn(HReturn* instruction ATTRIBUTE_UNUSED) { +void InstructionCodeGeneratorARM64::VisitReturn(HReturn* ret) { + if (GetGraph()->IsCompilingOsr()) { + // To simplify callers of an OSR method, we put the return value in both + // floating point and core register. + switch (ret->InputAt(0)->GetType()) { + case DataType::Type::kFloat32: + __ Fmov(w0, s0); + break; + case DataType::Type::kFloat64: + __ Fmov(x0, d0); + break; + default: + break; + } + } codegen_->GenerateFrameExit(); } diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index 4932a2c909..d4a41f7a03 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -3252,7 +3252,21 @@ void LocationsBuilderARMVIXL::VisitReturn(HReturn* ret) { locations->SetInAt(0, parameter_visitor_.GetReturnLocation(ret->InputAt(0)->GetType())); } -void InstructionCodeGeneratorARMVIXL::VisitReturn(HReturn* ret ATTRIBUTE_UNUSED) { +void InstructionCodeGeneratorARMVIXL::VisitReturn(HReturn* ret) { + if (GetGraph()->IsCompilingOsr()) { + // To simplify callers of an OSR method, we put the return value in both + // floating point and core registers. + switch (ret->InputAt(0)->GetType()) { + case DataType::Type::kFloat32: + __ Vmov(r0, s0); + break; + case DataType::Type::kFloat64: + __ Vmov(r0, r1, d0); + break; + default: + break; + } + } codegen_->GenerateFrameExit(); } diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index c3cd25cb17..f02ab26be8 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -2212,31 +2212,46 @@ void LocationsBuilderX86::VisitReturn(HReturn* ret) { } void InstructionCodeGeneratorX86::VisitReturn(HReturn* ret) { - if (kIsDebugBuild) { - switch (ret->InputAt(0)->GetType()) { - case DataType::Type::kReference: - case DataType::Type::kBool: - case DataType::Type::kUint8: - case DataType::Type::kInt8: - case DataType::Type::kUint16: - case DataType::Type::kInt16: - case DataType::Type::kInt32: - DCHECK_EQ(ret->GetLocations()->InAt(0).AsRegister<Register>(), EAX); - break; + switch (ret->InputAt(0)->GetType()) { + case DataType::Type::kReference: + case DataType::Type::kBool: + case DataType::Type::kUint8: + case DataType::Type::kInt8: + case DataType::Type::kUint16: + case DataType::Type::kInt16: + case DataType::Type::kInt32: + DCHECK_EQ(ret->GetLocations()->InAt(0).AsRegister<Register>(), EAX); + break; - case DataType::Type::kInt64: - DCHECK_EQ(ret->GetLocations()->InAt(0).AsRegisterPairLow<Register>(), EAX); - DCHECK_EQ(ret->GetLocations()->InAt(0).AsRegisterPairHigh<Register>(), EDX); - break; + case DataType::Type::kInt64: + DCHECK_EQ(ret->GetLocations()->InAt(0).AsRegisterPairLow<Register>(), EAX); + DCHECK_EQ(ret->GetLocations()->InAt(0).AsRegisterPairHigh<Register>(), EDX); + break; - case DataType::Type::kFloat32: - case DataType::Type::kFloat64: - DCHECK_EQ(ret->GetLocations()->InAt(0).AsFpuRegister<XmmRegister>(), XMM0); - break; + case DataType::Type::kFloat32: + DCHECK_EQ(ret->GetLocations()->InAt(0).AsFpuRegister<XmmRegister>(), XMM0); + if (GetGraph()->IsCompilingOsr()) { + // To simplify callers of an OSR method, we put the return value in both + // floating point and core registers. + __ movd(EAX, XMM0); + } + break; - default: - LOG(FATAL) << "Unknown return type " << ret->InputAt(0)->GetType(); - } + case DataType::Type::kFloat64: + DCHECK_EQ(ret->GetLocations()->InAt(0).AsFpuRegister<XmmRegister>(), XMM0); + if (GetGraph()->IsCompilingOsr()) { + // To simplify callers of an OSR method, we put the return value in both + // floating point and core registers. + __ movd(EAX, XMM0); + // Use XMM1 as temporary register to not clobber XMM0. + __ movaps(XMM1, XMM0); + __ psrlq(XMM1, Immediate(32)); + __ movd(EDX, XMM1); + } + break; + + default: + LOG(FATAL) << "Unknown return type " << ret->InputAt(0)->GetType(); } codegen_->GenerateFrameExit(); } diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index 5d4cfb4ecd..117277697d 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -2364,28 +2364,41 @@ void LocationsBuilderX86_64::VisitReturn(HReturn* ret) { } void InstructionCodeGeneratorX86_64::VisitReturn(HReturn* ret) { - if (kIsDebugBuild) { - switch (ret->InputAt(0)->GetType()) { - case DataType::Type::kReference: - case DataType::Type::kBool: - case DataType::Type::kUint8: - case DataType::Type::kInt8: - case DataType::Type::kUint16: - case DataType::Type::kInt16: - case DataType::Type::kInt32: - case DataType::Type::kInt64: - DCHECK_EQ(ret->GetLocations()->InAt(0).AsRegister<CpuRegister>().AsRegister(), RAX); - break; - - case DataType::Type::kFloat32: - case DataType::Type::kFloat64: - DCHECK_EQ(ret->GetLocations()->InAt(0).AsFpuRegister<XmmRegister>().AsFloatRegister(), - XMM0); - break; + switch (ret->InputAt(0)->GetType()) { + case DataType::Type::kReference: + case DataType::Type::kBool: + case DataType::Type::kUint8: + case DataType::Type::kInt8: + case DataType::Type::kUint16: + case DataType::Type::kInt16: + case DataType::Type::kInt32: + case DataType::Type::kInt64: + DCHECK_EQ(ret->GetLocations()->InAt(0).AsRegister<CpuRegister>().AsRegister(), RAX); + break; - default: - LOG(FATAL) << "Unexpected return type " << ret->InputAt(0)->GetType(); + case DataType::Type::kFloat32: { + DCHECK_EQ(ret->GetLocations()->InAt(0).AsFpuRegister<XmmRegister>().AsFloatRegister(), + XMM0); + // To simplify callers of an OSR method, we put the return value in both + // floating point and core register. + if (GetGraph()->IsCompilingOsr()) { + __ movd(CpuRegister(RAX), XmmRegister(XMM0), /* is64bit= */ false); + } + break; } + case DataType::Type::kFloat64: { + DCHECK_EQ(ret->GetLocations()->InAt(0).AsFpuRegister<XmmRegister>().AsFloatRegister(), + XMM0); + // To simplify callers of an OSR method, we put the return value in both + // floating point and core register. + if (GetGraph()->IsCompilingOsr()) { + __ movd(CpuRegister(RAX), XmmRegister(XMM0), /* is64bit= */ true); + } + break; + } + + default: + LOG(FATAL) << "Unexpected return type " << ret->InputAt(0)->GetType(); } codegen_->GenerateFrameExit(); } |