Skip to content

Commit e3323ae

Browse files
aartbikcommit-bot@chromium.org
authored andcommitted
[vm/inliner] Inline typed data on 32-bit archs.
Rationale: All recent improvements, now for 32-bit too. Performance: Many large improvements on micro benchmarks. Meteor down as expected. #33205 Change-Id: Ie9ebcfdfe9c5e265595c95d5e943ae35c5700a97 Reviewed-on: https://dart-review.googlesource.com/63685 Commit-Queue: Aart Bik <[email protected]> Reviewed-by: Vyacheslav Egorov <[email protected]>
1 parent f5a3af4 commit e3323ae

File tree

7 files changed

+148
-22
lines changed

7 files changed

+148
-22
lines changed

runtime/vm/compiler/assembler/assembler_arm.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2112,8 +2112,7 @@ OperandSize Address::OperandSizeFor(intptr_t cid) {
21122112
return kUnsignedWord;
21132113
case kTypedDataInt64ArrayCid:
21142114
case kTypedDataUint64ArrayCid:
2115-
UNREACHABLE();
2116-
return kByte;
2115+
return kDWord;
21172116
case kTypedDataFloat32ArrayCid:
21182117
return kSWord;
21192118
case kTypedDataFloat64ArrayCid:

runtime/vm/compiler/assembler/assembler_ia32.cc

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2512,12 +2512,13 @@ Address Assembler::ElementAddressForIntIndex(bool is_external,
25122512
intptr_t cid,
25132513
intptr_t index_scale,
25142514
Register array,
2515-
intptr_t index) {
2515+
intptr_t index,
2516+
intptr_t extra_disp) {
25162517
if (is_external) {
2517-
return Address(array, index * index_scale);
2518+
return Address(array, index * index_scale + extra_disp);
25182519
} else {
25192520
const int64_t disp = static_cast<int64_t>(index) * index_scale +
2520-
Instance::DataOffsetFor(cid);
2521+
Instance::DataOffsetFor(cid) + extra_disp;
25212522
ASSERT(Utils::IsInt(32, disp));
25222523
return FieldAddress(array, static_cast<int32_t>(disp));
25232524
}
@@ -2549,12 +2550,13 @@ Address Assembler::ElementAddressForRegIndex(bool is_external,
25492550
intptr_t cid,
25502551
intptr_t index_scale,
25512552
Register array,
2552-
Register index) {
2553+
Register index,
2554+
intptr_t extra_disp) {
25532555
if (is_external) {
2554-
return Address(array, index, ToScaleFactor(index_scale), 0);
2556+
return Address(array, index, ToScaleFactor(index_scale), extra_disp);
25552557
} else {
25562558
return FieldAddress(array, index, ToScaleFactor(index_scale),
2557-
Instance::DataOffsetFor(cid));
2559+
Instance::DataOffsetFor(cid) + extra_disp);
25582560
}
25592561
}
25602562

runtime/vm/compiler/assembler/assembler_ia32.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -672,13 +672,15 @@ class Assembler : public ValueObject {
672672
intptr_t cid,
673673
intptr_t index_scale,
674674
Register array,
675-
intptr_t index);
675+
intptr_t index,
676+
intptr_t extra_disp = 0);
676677

677678
static Address ElementAddressForRegIndex(bool is_external,
678679
intptr_t cid,
679680
intptr_t index_scale,
680681
Register array,
681-
Register index);
682+
Register index,
683+
intptr_t extra_disp = 0);
682684

683685
static Address VMTagAddress() {
684686
return Address(THR, Thread::vm_tag_offset());

runtime/vm/compiler/backend/il_arm.cc

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,6 +1131,8 @@ CompileType LoadIndexedInstr::ComputeType() const {
11311131

11321132
case kTypedDataInt32ArrayCid:
11331133
case kTypedDataUint32ArrayCid:
1134+
case kTypedDataInt64ArrayCid:
1135+
case kTypedDataUint64ArrayCid:
11341136
return CompileType::Int();
11351137

11361138
default:
@@ -1159,6 +1161,9 @@ Representation LoadIndexedInstr::representation() const {
11591161
return kUnboxedInt32;
11601162
case kTypedDataUint32ArrayCid:
11611163
return kUnboxedUint32;
1164+
case kTypedDataInt64ArrayCid:
1165+
case kTypedDataUint64ArrayCid:
1166+
return kUnboxedInt64;
11621167
case kTypedDataFloat32ArrayCid:
11631168
case kTypedDataFloat64ArrayCid:
11641169
return kUnboxedDouble;
@@ -1213,9 +1218,12 @@ static bool CanBeImmediateIndex(Value* value,
12131218

12141219
LocationSummary* LoadIndexedInstr::MakeLocationSummary(Zone* zone,
12151220
bool opt) const {
1221+
const bool directly_addressable =
1222+
aligned() && representation() != kUnboxedInt64;
12161223
const intptr_t kNumInputs = 2;
12171224
intptr_t kNumTemps = 0;
1218-
if (!aligned()) {
1225+
1226+
if (!directly_addressable) {
12191227
kNumTemps += 1;
12201228
if (representation() == kUnboxedDouble) {
12211229
kNumTemps += 1;
@@ -1251,11 +1259,16 @@ LocationSummary* LoadIndexedInstr::MakeLocationSummary(Zone* zone,
12511259
} else if (representation() == kUnboxedInt32) {
12521260
ASSERT(class_id() == kTypedDataInt32ArrayCid);
12531261
locs->set_out(0, Location::RequiresRegister());
1262+
} else if (representation() == kUnboxedInt64) {
1263+
ASSERT(class_id() == kTypedDataInt64ArrayCid ||
1264+
class_id() == kTypedDataUint64ArrayCid);
1265+
locs->set_out(0, Location::Pair(Location::RequiresRegister(),
1266+
Location::RequiresRegister()));
12541267
} else {
12551268
ASSERT(representation() == kTagged);
12561269
locs->set_out(0, Location::RequiresRegister());
12571270
}
1258-
if (!aligned()) {
1271+
if (!directly_addressable) {
12591272
locs->set_temp(0, Location::RequiresRegister());
12601273
if (representation() == kUnboxedDouble) {
12611274
locs->set_temp(1, Location::RequiresRegister());
@@ -1265,13 +1278,16 @@ LocationSummary* LoadIndexedInstr::MakeLocationSummary(Zone* zone,
12651278
}
12661279

12671280
void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1281+
const bool directly_addressable =
1282+
aligned() && representation() != kUnboxedInt64;
12681283
// The array register points to the backing store for external arrays.
12691284
const Register array = locs()->in(0).reg();
12701285
const Location index = locs()->in(1);
1271-
const Register address = aligned() ? kNoRegister : locs()->temp(0).reg();
1286+
const Register address =
1287+
directly_addressable ? kNoRegister : locs()->temp(0).reg();
12721288

12731289
Address element_address(kNoRegister);
1274-
if (aligned()) {
1290+
if (directly_addressable) {
12751291
element_address = index.IsRegister()
12761292
? __ ElementAddressForRegIndex(
12771293
true, // Load.
@@ -1368,6 +1384,25 @@ void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
13681384
return;
13691385
}
13701386

1387+
if (representation() == kUnboxedInt64) {
1388+
ASSERT(!directly_addressable); // need to add to register
1389+
ASSERT(class_id() == kTypedDataInt64ArrayCid ||
1390+
class_id() == kTypedDataUint64ArrayCid);
1391+
ASSERT(locs()->out(0).IsPairLocation());
1392+
PairLocation* result_pair = locs()->out(0).AsPairLocation();
1393+
Register result_lo = result_pair->At(0).reg();
1394+
Register result_hi = result_pair->At(1).reg();
1395+
if (aligned()) {
1396+
__ ldr(result_lo, Address(address));
1397+
__ ldr(result_hi, Address(address, kWordSize));
1398+
} else {
1399+
__ LoadWordUnaligned(result_lo, address, TMP);
1400+
__ AddImmediate(address, address, kWordSize);
1401+
__ LoadWordUnaligned(result_hi, address, TMP);
1402+
}
1403+
return;
1404+
}
1405+
13711406
ASSERT(representation() == kTagged);
13721407

13731408
const Register result = locs()->out(0).reg();
@@ -1435,6 +1470,9 @@ Representation StoreIndexedInstr::RequiredInputRepresentation(
14351470
return kUnboxedInt32;
14361471
case kTypedDataUint32ArrayCid:
14371472
return kUnboxedUint32;
1473+
case kTypedDataInt64ArrayCid:
1474+
case kTypedDataUint64ArrayCid:
1475+
return kUnboxedInt64;
14381476
case kTypedDataFloat32ArrayCid:
14391477
case kTypedDataFloat64ArrayCid:
14401478
return kUnboxedDouble;
@@ -1452,6 +1490,9 @@ Representation StoreIndexedInstr::RequiredInputRepresentation(
14521490

14531491
LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone,
14541492
bool opt) const {
1493+
const bool directly_addressable = aligned() &&
1494+
class_id() != kTypedDataInt64ArrayCid &&
1495+
class_id() != kTypedDataUint64ArrayCid;
14551496
const intptr_t kNumInputs = 3;
14561497
LocationSummary* locs;
14571498

@@ -1460,7 +1501,7 @@ LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone,
14601501
if (CanBeImmediateIndex(index(), class_id(), IsExternal(),
14611502
false, // Store.
14621503
&needs_base)) {
1463-
if (!aligned()) {
1504+
if (!directly_addressable) {
14641505
kNumTemps += 2;
14651506
} else if (needs_base) {
14661507
kNumTemps += 1;
@@ -1472,7 +1513,7 @@ LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone,
14721513
// CanBeImmediateIndex must return false for unsafe smis.
14731514
locs->set_in(1, Location::Constant(index()->definition()->AsConstant()));
14741515
} else {
1475-
if (!aligned()) {
1516+
if (!directly_addressable) {
14761517
kNumTemps += 2;
14771518
}
14781519

@@ -1504,6 +1545,11 @@ LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone,
15041545
case kTypedDataUint32ArrayCid:
15051546
locs->set_in(2, Location::RequiresRegister());
15061547
break;
1548+
case kTypedDataInt64ArrayCid:
1549+
case kTypedDataUint64ArrayCid:
1550+
locs->set_in(2, Location::Pair(Location::RequiresRegister(),
1551+
Location::RequiresRegister()));
1552+
break;
15071553
case kTypedDataFloat32ArrayCid:
15081554
// Need low register (<= Q7).
15091555
locs->set_in(2, Location::FpuRegisterLocation(Q7));
@@ -1522,6 +1568,9 @@ LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone,
15221568
}
15231569

15241570
void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1571+
const bool directly_addressable = aligned() &&
1572+
class_id() != kTypedDataInt64ArrayCid &&
1573+
class_id() != kTypedDataUint64ArrayCid;
15251574
// The array register points to the backing store for external arrays.
15261575
const Register array = locs()->in(0).reg();
15271576
const Location index = locs()->in(1);
@@ -1531,7 +1580,7 @@ void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
15311580
(locs()->temp_count() > 1) ? locs()->temp(1).reg() : kNoRegister;
15321581

15331582
Address element_address(kNoRegister);
1534-
if (aligned()) {
1583+
if (directly_addressable) {
15351584
element_address = index.IsRegister()
15361585
? __ ElementAddressForRegIndex(
15371586
false, // Store.
@@ -1630,6 +1679,23 @@ void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
16301679
}
16311680
break;
16321681
}
1682+
case kTypedDataInt64ArrayCid:
1683+
case kTypedDataUint64ArrayCid: {
1684+
ASSERT(!directly_addressable); // need to add to register
1685+
ASSERT(locs()->in(2).IsPairLocation());
1686+
PairLocation* value_pair = locs()->in(2).AsPairLocation();
1687+
Register value_lo = value_pair->At(0).reg();
1688+
Register value_hi = value_pair->At(1).reg();
1689+
if (aligned()) {
1690+
__ str(value_lo, Address(temp));
1691+
__ str(value_hi, Address(temp, kWordSize));
1692+
} else {
1693+
__ StoreWordUnaligned(value_lo, temp, temp2);
1694+
__ AddImmediate(temp, temp, kWordSize);
1695+
__ StoreWordUnaligned(value_hi, temp, temp2);
1696+
}
1697+
break;
1698+
}
16331699
case kTypedDataFloat32ArrayCid: {
16341700
const SRegister value_reg =
16351701
EvenSRegisterOf(EvenDRegisterOf(locs()->in(2).fpu_reg()));

runtime/vm/compiler/backend/il_ia32.cc

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,8 @@ CompileType LoadIndexedInstr::ComputeType() const {
10111011

10121012
case kTypedDataInt32ArrayCid:
10131013
case kTypedDataUint32ArrayCid:
1014+
case kTypedDataInt64ArrayCid:
1015+
case kTypedDataUint64ArrayCid:
10141016
return CompileType::Int();
10151017

10161018
default:
@@ -1039,6 +1041,9 @@ Representation LoadIndexedInstr::representation() const {
10391041
return kUnboxedInt32;
10401042
case kTypedDataUint32ArrayCid:
10411043
return kUnboxedUint32;
1044+
case kTypedDataInt64ArrayCid:
1045+
case kTypedDataUint64ArrayCid:
1046+
return kUnboxedInt64;
10421047
case kTypedDataFloat32ArrayCid:
10431048
case kTypedDataFloat64ArrayCid:
10441049
return kUnboxedDouble;
@@ -1081,6 +1086,11 @@ LocationSummary* LoadIndexedInstr::MakeLocationSummary(Zone* zone,
10811086
} else if (representation() == kUnboxedInt32) {
10821087
ASSERT(class_id() == kTypedDataInt32ArrayCid);
10831088
locs->set_out(0, Location::RequiresRegister());
1089+
} else if (representation() == kUnboxedInt64) {
1090+
ASSERT(class_id() == kTypedDataInt64ArrayCid ||
1091+
class_id() == kTypedDataUint64ArrayCid);
1092+
locs->set_out(0, Location::Pair(Location::RequiresRegister(),
1093+
Location::RequiresRegister()));
10841094
} else {
10851095
ASSERT(representation() == kTagged);
10861096
locs->set_out(0, Location::RequiresRegister());
@@ -1148,6 +1158,28 @@ void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
11481158
return;
11491159
}
11501160

1161+
if (representation() == kUnboxedInt64) {
1162+
ASSERT(locs()->out(0).IsPairLocation());
1163+
PairLocation* result_pair = locs()->out(0).AsPairLocation();
1164+
Register result_lo = result_pair->At(0).reg();
1165+
Register result_hi = result_pair->At(1).reg();
1166+
if ((index_scale() == 1) && index.IsRegister()) {
1167+
__ SmiUntag(index.reg());
1168+
}
1169+
ASSERT(class_id() == kTypedDataInt64ArrayCid ||
1170+
class_id() == kTypedDataUint64ArrayCid);
1171+
__ movl(result_lo, element_address);
1172+
element_address = index.IsRegister()
1173+
? Assembler::ElementAddressForRegIndex(
1174+
IsExternal(), class_id(), index_scale(), array,
1175+
index.reg(), kWordSize)
1176+
: Assembler::ElementAddressForIntIndex(
1177+
IsExternal(), class_id(), index_scale(), array,
1178+
Smi::Cast(index.constant()).Value(), kWordSize);
1179+
__ movl(result_hi, element_address);
1180+
return;
1181+
}
1182+
11511183
ASSERT(representation() == kTagged);
11521184

11531185
Register result = locs()->out(0).reg();
@@ -1208,6 +1240,9 @@ Representation StoreIndexedInstr::RequiredInputRepresentation(
12081240
return kUnboxedInt32;
12091241
case kTypedDataUint32ArrayCid:
12101242
return kUnboxedUint32;
1243+
case kTypedDataInt64ArrayCid:
1244+
case kTypedDataUint64ArrayCid:
1245+
return kUnboxedInt64;
12111246
case kTypedDataFloat32ArrayCid:
12121247
case kTypedDataFloat64ArrayCid:
12131248
return kUnboxedDouble;
@@ -1264,6 +1299,11 @@ LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone,
12641299
case kTypedDataUint32ArrayCid:
12651300
locs->set_in(2, Location::RequiresRegister());
12661301
break;
1302+
case kTypedDataInt64ArrayCid:
1303+
case kTypedDataUint64ArrayCid:
1304+
locs->set_in(2, Location::Pair(Location::RequiresRegister(),
1305+
Location::RequiresRegister()));
1306+
break;
12671307
case kTypedDataFloat32ArrayCid:
12681308
case kTypedDataFloat64ArrayCid:
12691309
// TODO(srdjan): Support Float64 constants.
@@ -1364,6 +1404,24 @@ void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
13641404
case kTypedDataUint32ArrayCid:
13651405
__ movl(element_address, locs()->in(2).reg());
13661406
break;
1407+
case kTypedDataInt64ArrayCid:
1408+
case kTypedDataUint64ArrayCid: {
1409+
ASSERT(locs()->in(2).IsPairLocation());
1410+
PairLocation* value_pair = locs()->in(2).AsPairLocation();
1411+
Register value_lo = value_pair->At(0).reg();
1412+
Register value_hi = value_pair->At(1).reg();
1413+
__ movl(element_address, value_lo);
1414+
element_address =
1415+
index.IsRegister()
1416+
? Assembler::ElementAddressForRegIndex(IsExternal(), class_id(),
1417+
index_scale(), array,
1418+
index.reg(), kWordSize)
1419+
: Assembler::ElementAddressForIntIndex(
1420+
IsExternal(), class_id(), index_scale(), array,
1421+
Smi::Cast(index.constant()).Value(), kWordSize);
1422+
__ movl(element_address, value_hi);
1423+
break;
1424+
}
13671425
case kTypedDataFloat32ArrayCid:
13681426
__ movss(element_address, locs()->in(2).fpu_reg());
13691427
break;

runtime/vm/compiler/backend/inliner.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2258,8 +2258,7 @@ static bool CanUnboxDouble() {
22582258
}
22592259

22602260
static bool ShouldInlineInt64ArrayOps() {
2261-
// TODO(ajcbik): look into doing this even for 32-bit targets.
2262-
return (kBitsPerWord == 64) && FlowGraphCompiler::SupportsUnboxedInt64();
2261+
return FlowGraphCompiler::SupportsUnboxedInt64();
22632262
}
22642263

22652264
static bool CanUnboxInt32() {

runtime/vm/compiler/call_specializer.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,12 +212,12 @@ bool CallSpecializer::TryCreateICData(InstanceCallInstr* call) {
212212
}
213213

214214
const Token::Kind op_kind = call->token_kind();
215-
if (FLAG_precompiled_mode && FLAG_strong && kBitsPerWord == 64) {
216-
// Avoid speculation for AOT Dart2 64-bit targets.
215+
if (FLAG_precompiled_mode && FLAG_strong) {
216+
// Avoid speculation for AOT Dart2 targets.
217217
//
218218
// TODO(ajcbik): expand this to more and more targets as we
219219
// investigate the performance impact of moving smi decision
220-
// into a later phase.
220+
// into a later phase, and recover from Meteor loss.
221221
//
222222
} else if (FLAG_guess_icdata_cid) {
223223
if (FLAG_precompiled_mode) {

0 commit comments

Comments
 (0)