[vm, compiler] Avoid one indirection when loading double constants. TEST=ci Change-Id: I3fc0a506121c660ae6c15a7c5e112fdf93a8ad90 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/224400 Reviewed-by: Alexander Markov <alexmarkov@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com>
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc index 0c396e7..12398f9 100644 --- a/runtime/vm/compiler/assembler/assembler_x64.cc +++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -1379,6 +1379,17 @@ } } +void Assembler::LoadDImmediate(FpuRegister dst, double immediate) { + int64_t bits = bit_cast<int64_t>(immediate); + if (bits == 0) { + xorps(dst, dst); + } else { + intptr_t index = FindImmediate(bits); + LoadUnboxedDouble( + dst, PP, target::ObjectPool::element_offset(index) - kHeapObjectTag); + } +} + void Assembler::LoadCompressed(Register dest, const Address& slot) { #if !defined(DART_COMPRESSED_POINTERS) movq(dest, slot);
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h index 5312859..3f4bf92 100644 --- a/runtime/vm/compiler/assembler/assembler_x64.h +++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -747,6 +747,7 @@ void LoadImmediate(Register reg, int32_t immediate) { LoadImmediate(reg, Immediate(immediate)); } + void LoadDImmediate(FpuRegister dst, double immediate); void LoadIsolate(Register dst); void LoadIsolateGroup(Register dst);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc index 91cc786..bed125b 100644 --- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc +++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -866,14 +866,7 @@ } else { ASSERT(!source.IsInvalid()); ASSERT(source.IsConstant()); - if (destination.IsFpuRegister() || destination.IsDoubleStackSlot()) { - Register scratch = tmp->AllocateTemporary(); - source.constant_instruction()->EmitMoveToLocation(this, destination, - scratch); - tmp->ReleaseTemporary(); - } else { - source.constant_instruction()->EmitMoveToLocation(this, destination); - } + source.constant_instruction()->EmitMoveToLocation(this, destination); } }
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc index 378537a..3066d10 100644 --- a/runtime/vm/compiler/backend/il_x64.cc +++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -560,22 +560,9 @@ __ LoadObject(destination.reg(), value_); } } else if (destination.IsFpuRegister()) { - if (Utils::DoublesBitEqual(Double::Cast(value_).value(), 0.0)) { - __ xorps(destination.fpu_reg(), destination.fpu_reg()); - } else { - ASSERT(tmp != kNoRegister); - __ LoadObject(tmp, value_); - __ movsd(destination.fpu_reg(), - compiler::FieldAddress(tmp, Double::value_offset())); - } + __ LoadDImmediate(destination.fpu_reg(), Double::Cast(value_).value()); } else if (destination.IsDoubleStackSlot()) { - if (Utils::DoublesBitEqual(Double::Cast(value_).value(), 0.0)) { - __ xorps(FpuTMP, FpuTMP); - } else { - ASSERT(tmp != kNoRegister); - __ LoadObject(tmp, value_); - __ movsd(FpuTMP, compiler::FieldAddress(tmp, Double::value_offset())); - } + __ LoadDImmediate(FpuTMP, Double::Cast(value_).value()); __ movsd(LocationToStackSlotAddress(destination), FpuTMP); } else { ASSERT(destination.IsStackSlot()); @@ -5438,13 +5425,11 @@ XmmRegister base = locs->in(0).fpu_reg(); XmmRegister exp = locs->in(1).fpu_reg(); XmmRegister result = locs->out(0).fpu_reg(); - Register temp = locs->temp(InvokeMathCFunctionInstr::kObjectTempIndex).reg(); XmmRegister zero_temp = locs->temp(InvokeMathCFunctionInstr::kDoubleTempIndex).fpu_reg(); __ xorps(zero_temp, zero_temp); - __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1))); - __ movsd(result, compiler::FieldAddress(temp, Double::value_offset())); + __ LoadDImmediate(result, 1.0); compiler::Label check_base, skip_call; // exponent == 0.0 -> return 1.0; @@ -5458,15 +5443,13 @@ __ j(EQUAL, &return_base, compiler::Assembler::kNearJump); // exponent == 2.0 ? - __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(2.0))); - __ movsd(XMM0, compiler::FieldAddress(temp, Double::value_offset())); + __ LoadDImmediate(XMM0, 2.0); __ comisd(exp, XMM0); compiler::Label return_base_times_2; __ j(EQUAL, &return_base_times_2, compiler::Assembler::kNearJump); // exponent == 3.0 ? - __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(3.0))); - __ movsd(XMM0, compiler::FieldAddress(temp, Double::value_offset())); + __ LoadDImmediate(XMM0, 3.0); __ comisd(exp, XMM0); __ j(NOT_EQUAL, &check_base); @@ -5500,22 +5483,19 @@ __ j(PARITY_ODD, &try_sqrt, compiler::Assembler::kNearJump); // Return NaN. __ Bind(&return_nan); - __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(NAN))); - __ movsd(result, compiler::FieldAddress(temp, Double::value_offset())); + __ LoadDImmediate(result, NAN); __ jmp(&skip_call); compiler::Label do_pow, return_zero; __ Bind(&try_sqrt); // Before calling pow, check if we could use sqrt instead of pow. - __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(kNegInfinity))); - __ movsd(result, compiler::FieldAddress(temp, Double::value_offset())); + __ LoadDImmediate(result, kNegInfinity); // base == -Infinity -> call pow; __ comisd(base, result); __ j(EQUAL, &do_pow, compiler::Assembler::kNearJump); // exponent == 0.5 ? - __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0.5))); - __ movsd(result, compiler::FieldAddress(temp, Double::value_offset())); + __ LoadDImmediate(result, 0.5); __ comisd(exp, result); __ j(NOT_EQUAL, &do_pow, compiler::Assembler::kNearJump);