[vm, x64] Shorter UnboxInt64Instr with compressed Smis.

TEST=ci
Change-Id: Ib80b9cd80f3656ea6c5f31e0dbc7229632d8783d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/198140
Reviewed-by: Liam Appelbe <liama@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Ryan Macnak 2021-05-12 17:02:10 +00:00 committed by commit-bot@chromium.org
parent 7131d3182c
commit b4c64a1787
2 changed files with 45 additions and 28 deletions

View file

@ -895,6 +895,12 @@ class Assembler : public AssemblerBase {
void SmiTag(Register reg) { OBJ(add)(reg, reg); } void SmiTag(Register reg) { OBJ(add)(reg, reg); }
void SmiUntag(Register reg) { OBJ(sar)(reg, Immediate(kSmiTagSize)); } void SmiUntag(Register reg) { OBJ(sar)(reg, Immediate(kSmiTagSize)); }
void SmiUntag(Register dst, Register src) {
if (dst != src) {
OBJ(mov)(dst, src);
}
OBJ(sar)(dst, Immediate(kSmiTagSize));
}
void SmiUntagAndSignExtend(Register reg) { void SmiUntagAndSignExtend(Register reg) {
#if !defined(DART_COMPRESSED_POINTERS) #if !defined(DART_COMPRESSED_POINTERS)
@ -903,11 +909,23 @@ class Assembler : public AssemblerBase {
// This is shorter than // This is shorter than
// shlq reg, 32 // shlq reg, 32
// sraq reg, 33 // sraq reg, 33
sarl(reg, Immediate(1)); sarl(reg, Immediate(kSmiTagSize));
movsxd(reg, reg); movsxd(reg, reg);
#endif #endif
} }
void SmiUntagAndSignExtend(Register dst, Register src) {
#if !defined(DART_COMPRESSED_POINTERS)
if (dst != src) {
movq(dst, src);
}
sarq(dst, Immediate(kSmiTagSize));
#else
movsxd(dst, src);
sarq(dst, Immediate(kSmiTagSize));
#endif
}
void BranchIfNotSmi(Register reg, void BranchIfNotSmi(Register reg,
Label* label, Label* label,
JumpDistance distance = kFarJump) { JumpDistance distance = kFarJump) {

View file

@ -4074,7 +4074,11 @@ LocationSummary* UnboxInstr::MakeLocationSummary(Zone* zone, bool opt) const {
summary->set_in(0, needs_writable_input ? Location::WritableRegister() summary->set_in(0, needs_writable_input ? Location::WritableRegister()
: Location::RequiresRegister()); : Location::RequiresRegister());
if (RepresentationUtils::IsUnboxedInteger(representation())) { if (RepresentationUtils::IsUnboxedInteger(representation())) {
#if !defined(DART_COMPRESSED_POINTERS)
summary->set_out(0, Location::SameAsFirstInput()); summary->set_out(0, Location::SameAsFirstInput());
#else
summary->set_out(0, Location::RequiresRegister());
#endif
} else { } else {
summary->set_out(0, Location::RequiresFpuRegister()); summary->set_out(0, Location::RequiresFpuRegister());
} }
@ -4122,14 +4126,16 @@ void UnboxInstr::EmitSmiConversion(FlowGraphCompiler* compiler) {
const Register box = locs()->in(0).reg(); const Register box = locs()->in(0).reg();
switch (representation()) { switch (representation()) {
case kUnboxedInt32: case kUnboxedInt32: {
case kUnboxedInt64: {
const Register result = locs()->out(0).reg(); const Register result = locs()->out(0).reg();
ASSERT(result == box); __ SmiUntag(result, box);
__ SmiUntagAndSignExtend(box); break;
}
case kUnboxedInt64: {
const Register result = locs()->out(0).reg();
__ SmiUntagAndSignExtend(result, box);
break; break;
} }
case kUnboxedDouble: { case kUnboxedDouble: {
const FpuRegister result = locs()->out(0).fpu_reg(); const FpuRegister result = locs()->out(0).fpu_reg();
__ SmiUntag(box); __ SmiUntag(box);
@ -4146,22 +4152,18 @@ void UnboxInstr::EmitSmiConversion(FlowGraphCompiler* compiler) {
void UnboxInstr::EmitLoadInt32FromBoxOrSmi(FlowGraphCompiler* compiler) { void UnboxInstr::EmitLoadInt32FromBoxOrSmi(FlowGraphCompiler* compiler) {
const Register value = locs()->in(0).reg(); const Register value = locs()->in(0).reg();
const Register result = locs()->out(0).reg(); const Register result = locs()->out(0).reg();
ASSERT(value == result);
compiler::Label done; compiler::Label done;
#if !defined(DART_COMPRESSED_POINTERS) #if !defined(DART_COMPRESSED_POINTERS)
ASSERT(value == result);
__ SmiUntag(value); __ SmiUntag(value);
__ j(NOT_CARRY, &done, compiler::Assembler::kNearJump); __ j(NOT_CARRY, &done, compiler::Assembler::kNearJump);
__ movsxw(result, compiler::Address(value, TIMES_2, Mint::value_offset())); __ movsxw(result, compiler::Address(value, TIMES_2, Mint::value_offset()));
#else #else
// Cannot speculatively untag because it erases the upper bits needed to ASSERT(value != result);
// dereference when it is a Mint. // Cannot speculatively untag with value == result because it erases the
// TODO(compressed-pointers): It would probably be cheaper to make // upper bits needed to dereference when it is a Mint.
// result != value with compressed pointers. __ SmiUntagAndSignExtend(result, value);
compiler::Label not_smi; __ j(NOT_CARRY, &done, compiler::Assembler::kNearJump);
__ BranchIfNotSmi(value, &not_smi, compiler::Assembler::kNearJump);
__ SmiUntagAndSignExtend(value);
__ jmp(&done, compiler::Assembler::kNearJump);
__ Bind(&not_smi);
__ movsxw(result, compiler::FieldAddress(value, Mint::value_offset())); __ movsxw(result, compiler::FieldAddress(value, Mint::value_offset()));
#endif #endif
__ Bind(&done); __ Bind(&done);
@ -4170,24 +4172,21 @@ void UnboxInstr::EmitLoadInt32FromBoxOrSmi(FlowGraphCompiler* compiler) {
void UnboxInstr::EmitLoadInt64FromBoxOrSmi(FlowGraphCompiler* compiler) { void UnboxInstr::EmitLoadInt64FromBoxOrSmi(FlowGraphCompiler* compiler) {
const Register value = locs()->in(0).reg(); const Register value = locs()->in(0).reg();
const Register result = locs()->out(0).reg(); const Register result = locs()->out(0).reg();
ASSERT(value == result);
compiler::Label done; compiler::Label done;
#if !defined(DART_COMPRESSED_POINTERS) #if !defined(DART_COMPRESSED_POINTERS)
ASSERT(value == result);
__ SmiUntag(value); __ SmiUntag(value);
__ j(NOT_CARRY, &done, compiler::Assembler::kNearJump); __ j(NOT_CARRY, &done, compiler::Assembler::kNearJump);
__ movq(value, compiler::Address(value, TIMES_2, Mint::value_offset())); __ movq(result, compiler::Address(value, TIMES_2, Mint::value_offset()));
__ Bind(&done);
#else #else
// Cannot speculatively untag because it erases the upper bits needed to ASSERT(value != result);
// dereference when it is a Mint. // Cannot speculatively untag with value == result because it erases the
compiler::Label not_smi; // upper bits needed to dereference when it is a Mint.
__ BranchIfNotSmi(value, &not_smi, compiler::Assembler::kNearJump); __ SmiUntagAndSignExtend(result, value);
__ SmiUntagAndSignExtend(value); __ j(NOT_CARRY, &done, compiler::Assembler::kNearJump);
__ jmp(&done, compiler::Assembler::kNearJump); __ movq(result, compiler::FieldAddress(value, Mint::value_offset()));
__ Bind(&not_smi);
__ movq(value, compiler::FieldAddress(value, Mint::value_offset()));
__ Bind(&done);
#endif #endif
__ Bind(&done);
} }
LocationSummary* UnboxInteger32Instr::MakeLocationSummary(Zone* zone, LocationSummary* UnboxInteger32Instr::MakeLocationSummary(Zone* zone,