Skip to content

Commit 72355d5

Browse files
ErikCorryGooglecommit-bot@chromium.org
authored andcommitted
[VM] IA32: Make register allocation around boxing clearer
[email protected] Bug: Change-Id: I96f01a61272a886294aadc877dc130f0bb011693 Reviewed-on: https://dart-review.googlesource.com/33942 Commit-Queue: Erik Corry <[email protected]> Reviewed-by: Vyacheslav Egorov <[email protected]>
1 parent 6079f6a commit 72355d5

File tree

1 file changed

+56
-37
lines changed

1 file changed

+56
-37
lines changed

runtime/vm/compiler/backend/il_ia32.cc

Lines changed: 56 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1819,7 +1819,8 @@ void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
18191819

18201820
if (ShouldEmitStoreBarrier()) {
18211821
// Value input is a writable register and should be manually preserved
1822-
// across allocation slow-path.
1822+
// across allocation slow-path. Add it to live_registers set which
1823+
// determines which registers to preserve.
18231824
locs()->live_registers()->Add(locs()->in(1), kTagged);
18241825
}
18251826

@@ -3448,54 +3449,70 @@ LocationSummary* BoxInteger32Instr::MakeLocationSummary(Zone* zone,
34483449
bool opt) const {
34493450
const intptr_t kNumInputs = 1;
34503451
const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1;
3451-
LocationSummary* summary = new (zone)
3452-
LocationSummary(zone, kNumInputs, kNumTemps,
3453-
ValueFitsSmi() ? LocationSummary::kNoCall
3454-
: LocationSummary::kCallOnSlowPath);
3455-
const bool needs_writable_input =
3456-
ValueFitsSmi() || (from_representation() == kUnboxedUint32);
3457-
summary->set_in(0, needs_writable_input ? Location::RequiresRegister()
3458-
: Location::WritableRegister());
3459-
if (!ValueFitsSmi()) {
3452+
if (ValueFitsSmi()) {
3453+
LocationSummary* summary = new (zone)
3454+
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3455+
// Same regs, can overwrite input.
3456+
summary->set_in(0, Location::RequiresRegister());
3457+
summary->set_out(0, Location::SameAsFirstInput());
3458+
return summary;
3459+
} else {
3460+
LocationSummary* summary = new (zone) LocationSummary(
3461+
zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
3462+
// Guaranteed different regs. In the signed case we are going to use the
3463+
// input for sign extension of any Mint.
3464+
const bool needs_writable_input = (from_representation() == kUnboxedInt32);
3465+
summary->set_in(0, needs_writable_input ? Location::WritableRegister()
3466+
: Location::RequiresRegister());
34603467
summary->set_temp(0, Location::RequiresRegister());
3468+
summary->set_out(0, Location::RequiresRegister());
3469+
return summary;
34613470
}
3462-
summary->set_out(0, ValueFitsSmi() ? Location::SameAsFirstInput()
3463-
: Location::RequiresRegister());
3464-
return summary;
34653471
}
34663472

34673473
void BoxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
34683474
const Register value = locs()->in(0).reg();
34693475
const Register out = locs()->out(0).reg();
34703476

3471-
__ MoveRegister(out, value);
3477+
if (ValueFitsSmi()) {
3478+
ASSERT(value == out);
3479+
ASSERT(kSmiTag == 0);
3480+
__ shll(out, Immediate(kSmiTagSize));
3481+
return;
3482+
}
3483+
3484+
__ movl(out, value);
34723485
__ shll(out, Immediate(kSmiTagSize));
3473-
if (!ValueFitsSmi()) {
3474-
Label done;
3475-
ASSERT(value != out);
3476-
if (from_representation() == kUnboxedInt32) {
3477-
__ j(NO_OVERFLOW, &done);
3478-
} else {
3479-
__ testl(value, Immediate(0xC0000000));
3480-
__ j(ZERO, &done);
3481-
}
3486+
Label done;
3487+
if (from_representation() == kUnboxedInt32) {
3488+
__ j(NO_OVERFLOW, &done);
3489+
} else {
3490+
ASSERT(value != out); // Value was not overwritten.
3491+
__ testl(value, Immediate(0xC0000000));
3492+
__ j(ZERO, &done);
3493+
}
34823494

3483-
// Allocate a mint.
3484-
// Value input is writable register and has to be manually preserved
3485-
// on the slow path.
3495+
// Allocate a Mint.
3496+
if (from_representation() == kUnboxedInt32) {
3497+
// Value input is a writable register and should be manually preserved
3498+
// across allocation slow-path. Add it to live_registers set which
3499+
// determines which registers to preserve.
34863500
locs()->live_registers()->Add(locs()->in(0), kUnboxedInt32);
3487-
BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(), out,
3488-
locs()->temp(0).reg());
3489-
__ movl(FieldAddress(out, Mint::value_offset()), value);
3490-
if (from_representation() == kUnboxedInt32) {
3491-
__ sarl(value, Immediate(31)); // Sign extend.
3492-
__ movl(FieldAddress(out, Mint::value_offset() + kWordSize), value);
3493-
} else {
3494-
__ movl(FieldAddress(out, Mint::value_offset() + kWordSize),
3495-
Immediate(0));
3496-
}
3497-
__ Bind(&done);
34983501
}
3502+
ASSERT(value != out); // We need the value after the allocation.
3503+
BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(), out,
3504+
locs()->temp(0).reg());
3505+
__ movl(FieldAddress(out, Mint::value_offset()), value);
3506+
if (from_representation() == kUnboxedInt32) {
3507+
// In the signed may-overflow case we asked for the input (value) to be
3508+
// writable so we can use it as a temp to put the sign extension bits in.
3509+
__ sarl(value, Immediate(31)); // Sign extend the Mint.
3510+
__ movl(FieldAddress(out, Mint::value_offset() + kWordSize), value);
3511+
} else {
3512+
__ movl(FieldAddress(out, Mint::value_offset() + kWordSize),
3513+
Immediate(0)); // Zero extend the Mint.
3514+
}
3515+
__ Bind(&done);
34993516
}
35003517

35013518
LocationSummary* BoxInt64Instr::MakeLocationSummary(Zone* zone,
@@ -3755,6 +3772,8 @@ void LoadCodeUnitsInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
37553772
Register temp = locs()->temp(0).reg();
37563773
Register temp2 = locs()->temp(1).reg();
37573774
// Temp register needs to be manually preserved on allocation slow-path.
3775+
// Add it to live_registers set which determines which registers to
3776+
// preserve.
37583777
locs()->live_registers()->Add(locs()->temp(0), kUnboxedInt32);
37593778

37603779
ASSERT(temp != result);

0 commit comments

Comments
 (0)