mirror of
https://github.com/dart-lang/sdk
synced 2024-09-18 21:21:18 +00:00
[vm, compiler] Handle large offsets with double spill slots on RISC-V.
Fix non-existent addressing mode in ARM fpu spilling. TEST=ci Change-Id: I0ecb973059a6cab11dce5b87137b54e0d1ac5ac5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/243703 Commit-Queue: Ryan Macnak <rmacnak@google.com> Reviewed-by: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
parent
f964af3bf3
commit
2cf4bf72a8
|
@ -2455,6 +2455,16 @@ void Assembler::PopList(RegList regs, Condition cond) {
|
||||||
ldm(IA_W, SP, regs, cond);
|
ldm(IA_W, SP, regs, cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Assembler::PushQuad(FpuRegister reg, Condition cond) {
|
||||||
|
DRegister dreg = EvenDRegisterOf(reg);
|
||||||
|
vstmd(DB_W, SP, dreg, 2, cond); // 2 D registers per Q register.
|
||||||
|
}
|
||||||
|
|
||||||
|
void Assembler::PopQuad(FpuRegister reg, Condition cond) {
|
||||||
|
DRegister dreg = EvenDRegisterOf(reg);
|
||||||
|
vldmd(IA_W, SP, dreg, 2, cond); // 2 D registers per Q register.
|
||||||
|
}
|
||||||
|
|
||||||
void Assembler::PushRegisters(const RegisterSet& regs) {
|
void Assembler::PushRegisters(const RegisterSet& regs) {
|
||||||
const intptr_t fpu_regs_count = regs.FpuRegisterCount();
|
const intptr_t fpu_regs_count = regs.FpuRegisterCount();
|
||||||
if (fpu_regs_count > 0) {
|
if (fpu_regs_count > 0) {
|
||||||
|
|
|
@ -1134,6 +1134,9 @@ class Assembler : public AssemblerBase {
|
||||||
void PushList(RegList regs, Condition cond = AL);
|
void PushList(RegList regs, Condition cond = AL);
|
||||||
void PopList(RegList regs, Condition cond = AL);
|
void PopList(RegList regs, Condition cond = AL);
|
||||||
|
|
||||||
|
void PushQuad(FpuRegister rd, Condition cond = AL);
|
||||||
|
void PopQuad(FpuRegister rd, Condition cond = AL);
|
||||||
|
|
||||||
void PushRegisters(const RegisterSet& regs);
|
void PushRegisters(const RegisterSet& regs);
|
||||||
void PopRegisters(const RegisterSet& regs);
|
void PopRegisters(const RegisterSet& regs);
|
||||||
|
|
||||||
|
|
|
@ -1271,15 +1271,11 @@ void ParallelMoveResolver::RestoreScratch(Register reg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParallelMoveResolver::SpillFpuScratch(FpuRegister reg) {
|
void ParallelMoveResolver::SpillFpuScratch(FpuRegister reg) {
|
||||||
DRegister dreg = EvenDRegisterOf(reg);
|
__ PushQuad(reg);
|
||||||
__ vstrd(dreg,
|
|
||||||
compiler::Address(SP, -kDoubleSize, compiler::Address::PreIndex));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) {
|
void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) {
|
||||||
DRegister dreg = EvenDRegisterOf(reg);
|
__ PopQuad(reg);
|
||||||
__ vldrd(dreg,
|
|
||||||
compiler::Address(SP, kDoubleSize, compiler::Address::PostIndex));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef __
|
#undef __
|
||||||
|
|
|
@ -1234,11 +1234,11 @@ void ParallelMoveResolver::RestoreScratch(Register reg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParallelMoveResolver::SpillFpuScratch(FpuRegister reg) {
|
void ParallelMoveResolver::SpillFpuScratch(FpuRegister reg) {
|
||||||
__ PushDouble(reg);
|
__ PushQuad(reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) {
|
void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) {
|
||||||
__ PopDouble(reg);
|
__ PopQuad(reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef __
|
#undef __
|
||||||
|
|
|
@ -819,7 +819,7 @@ void FlowGraphCompiler::EmitMove(Location destination,
|
||||||
} else if (destination.IsFpuRegister()) {
|
} else if (destination.IsFpuRegister()) {
|
||||||
const intptr_t src_offset = source.ToStackSlotOffset();
|
const intptr_t src_offset = source.ToStackSlotOffset();
|
||||||
FRegister dst = destination.fpu_reg();
|
FRegister dst = destination.fpu_reg();
|
||||||
__ fld(dst, compiler::Address(source.base_reg(), src_offset));
|
__ LoadDFromOffset(dst, source.base_reg(), src_offset);
|
||||||
} else {
|
} else {
|
||||||
ASSERT(destination.IsStackSlot());
|
ASSERT(destination.IsStackSlot());
|
||||||
const intptr_t source_offset = source.ToStackSlotOffset();
|
const intptr_t source_offset = source.ToStackSlotOffset();
|
||||||
|
@ -837,7 +837,7 @@ void FlowGraphCompiler::EmitMove(Location destination,
|
||||||
destination.IsDoubleStackSlot()) {
|
destination.IsDoubleStackSlot()) {
|
||||||
const intptr_t dest_offset = destination.ToStackSlotOffset();
|
const intptr_t dest_offset = destination.ToStackSlotOffset();
|
||||||
FRegister src = source.fpu_reg();
|
FRegister src = source.fpu_reg();
|
||||||
__ fsd(src, compiler::Address(destination.base_reg(), dest_offset));
|
__ StoreDToOffset(src, destination.base_reg(), dest_offset);
|
||||||
} else {
|
} else {
|
||||||
ASSERT(destination.IsQuadStackSlot());
|
ASSERT(destination.IsQuadStackSlot());
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
|
@ -847,14 +847,14 @@ void FlowGraphCompiler::EmitMove(Location destination,
|
||||||
if (destination.IsFpuRegister()) {
|
if (destination.IsFpuRegister()) {
|
||||||
const intptr_t source_offset = source.ToStackSlotOffset();
|
const intptr_t source_offset = source.ToStackSlotOffset();
|
||||||
const FRegister dst = destination.fpu_reg();
|
const FRegister dst = destination.fpu_reg();
|
||||||
__ fld(dst, compiler::Address(source.base_reg(), source_offset));
|
__ LoadDFromOffset(dst, source.base_reg(), source_offset);
|
||||||
} else {
|
} else {
|
||||||
ASSERT(destination.IsDoubleStackSlot() ||
|
ASSERT(destination.IsDoubleStackSlot() ||
|
||||||
destination.IsStackSlot() /*32-bit float*/);
|
destination.IsStackSlot() /*32-bit float*/);
|
||||||
const intptr_t source_offset = source.ToStackSlotOffset();
|
const intptr_t source_offset = source.ToStackSlotOffset();
|
||||||
const intptr_t dest_offset = destination.ToStackSlotOffset();
|
const intptr_t dest_offset = destination.ToStackSlotOffset();
|
||||||
__ fld(FTMP, compiler::Address(source.base_reg(), source_offset));
|
__ LoadDFromOffset(FTMP, source.base_reg(), source_offset);
|
||||||
__ fsd(FTMP, compiler::Address(destination.base_reg(), dest_offset));
|
__ StoreDToOffset(FTMP, destination.base_reg(), dest_offset);
|
||||||
}
|
}
|
||||||
} else if (source.IsQuadStackSlot()) {
|
} else if (source.IsQuadStackSlot()) {
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "platform/text_buffer.h"
|
||||||
#include "platform/utils.h"
|
#include "platform/utils.h"
|
||||||
#include "vm/compiler/backend/block_builder.h"
|
#include "vm/compiler/backend/block_builder.h"
|
||||||
#include "vm/compiler/backend/il_printer.h"
|
#include "vm/compiler/backend/il_printer.h"
|
||||||
|
@ -146,4 +147,101 @@ ISOLATE_UNIT_TEST_CASE(FlowGraph_LateVariablePhiUnboxing) {
|
||||||
EXPECT_PROPERTY(late_var, it.representation() == kTagged);
|
EXPECT_PROPERTY(late_var, it.representation() == kTagged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestLargeFrame(const char* type,
|
||||||
|
const char* zero,
|
||||||
|
const char* one,
|
||||||
|
const char* main) {
|
||||||
|
SetFlagScope<int> sfs(&FLAG_optimization_counter_threshold, 1000);
|
||||||
|
TextBuffer printer(256 * KB);
|
||||||
|
|
||||||
|
intptr_t num_locals = 2000;
|
||||||
|
printer.Printf("import 'dart:typed_data';\n");
|
||||||
|
printer.Printf("@pragma('vm:never-inline')\n");
|
||||||
|
printer.Printf("%s one() { return %s; }\n", type, one);
|
||||||
|
printer.Printf("@pragma('vm:never-inline')\n");
|
||||||
|
printer.Printf("%s largeFrame(int n) {\n", type);
|
||||||
|
for (intptr_t i = 0; i < num_locals; i++) {
|
||||||
|
printer.Printf(" %s local%" Pd " = %s;\n", type, i, zero);
|
||||||
|
}
|
||||||
|
printer.Printf(" for (int i = 0; i < n; i++) {\n");
|
||||||
|
for (intptr_t i = 0; i < num_locals; i++) {
|
||||||
|
printer.Printf(" local%" Pd " += one();\n", i);
|
||||||
|
}
|
||||||
|
printer.Printf(" }\n");
|
||||||
|
printer.Printf(" %s sum = %s;\n", type, zero);
|
||||||
|
for (intptr_t i = 0; i < num_locals; i++) {
|
||||||
|
printer.Printf(" sum += local%" Pd ";\n", i);
|
||||||
|
}
|
||||||
|
printer.Printf(" return sum;\n");
|
||||||
|
printer.Printf("}\n");
|
||||||
|
|
||||||
|
printer.AddString(main);
|
||||||
|
|
||||||
|
const auto& root_library = Library::Handle(LoadTestScript(printer.buffer()));
|
||||||
|
Invoke(root_library, "main");
|
||||||
|
}
|
||||||
|
|
||||||
|
ISOLATE_UNIT_TEST_CASE(FlowGraph_LargeFrame_Int) {
|
||||||
|
TestLargeFrame("int", "0", "1",
|
||||||
|
"main() {\n"
|
||||||
|
" for (var i = 0; i < 100; i++) {\n"
|
||||||
|
" var r = largeFrame(1);\n"
|
||||||
|
" if (r != 2000) throw r;\n"
|
||||||
|
" }\n"
|
||||||
|
" return 'Okay';\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
ISOLATE_UNIT_TEST_CASE(FlowGraph_LargeFrame_Double) {
|
||||||
|
TestLargeFrame("double", "0.0", "1.0",
|
||||||
|
"main() {\n"
|
||||||
|
" for (var i = 0; i < 100; i++) {\n"
|
||||||
|
" var r = largeFrame(1);\n"
|
||||||
|
" if (r != 2000.0) throw r;\n"
|
||||||
|
" }\n"
|
||||||
|
" return 'Okay';\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
ISOLATE_UNIT_TEST_CASE(FlowGraph_LargeFrame_Int32x4) {
|
||||||
|
TestLargeFrame("Int32x4", "Int32x4(0, 0, 0, 0)", "Int32x4(1, 2, 3, 4)",
|
||||||
|
"main() {\n"
|
||||||
|
" for (var i = 0; i < 100; i++) {\n"
|
||||||
|
" var r = largeFrame(1);\n"
|
||||||
|
" if (r.x != 2000) throw r;\n"
|
||||||
|
" if (r.y != 4000) throw r;\n"
|
||||||
|
" if (r.z != 6000) throw r;\n"
|
||||||
|
" if (r.w != 8000) throw r;\n"
|
||||||
|
" }\n"
|
||||||
|
" return 'Okay';\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
ISOLATE_UNIT_TEST_CASE(FlowGraph_LargeFrame_Float32x4) {
|
||||||
|
TestLargeFrame("Float32x4", "Float32x4(0.0, 0.0, 0.0, 0.0)",
|
||||||
|
"Float32x4(1.0, 2.0, 3.0, 4.0)",
|
||||||
|
"main() {\n"
|
||||||
|
" for (var i = 0; i < 100; i++) {\n"
|
||||||
|
" var r = largeFrame(1);\n"
|
||||||
|
" if (r.x != 2000.0) throw r;\n"
|
||||||
|
" if (r.y != 4000.0) throw r;\n"
|
||||||
|
" if (r.z != 6000.0) throw r;\n"
|
||||||
|
" if (r.w != 8000.0) throw r;\n"
|
||||||
|
" }\n"
|
||||||
|
" return 'Okay';\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
ISOLATE_UNIT_TEST_CASE(FlowGraph_LargeFrame_Float64x2) {
|
||||||
|
TestLargeFrame("Float64x2", "Float64x2(0.0, 0.0)", "Float64x2(1.0, 2.0)",
|
||||||
|
"main() {\n"
|
||||||
|
" for (var i = 0; i < 100; i++) {\n"
|
||||||
|
" var r = largeFrame(1);\n"
|
||||||
|
" if (r.x != 2000.0) throw r;\n"
|
||||||
|
" if (r.y != 4000.0) throw r;\n"
|
||||||
|
" }\n"
|
||||||
|
" return 'Okay';\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace dart
|
} // namespace dart
|
||||||
|
|
Loading…
Reference in a new issue