[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);