Skip to content

Commit 2a396d5

Browse files
aartbikcommit-bot@chromium.org
authored andcommitted
[vm/intrinsics] Intrinsify 64-bit int typed data.
Rationale: With limited integers, signed/unsigned 64-bit int typed data is just a bit pattern, no need to sign/zero extend these into bigger ints on load. This enables more intrinsification of indexed stores/loads. Note: Still TBD, inline these indexed operations too. Performance: About 10x improvement on micro benchmarks. #33205 Change-Id: I640c324a7d91e57fb4edc025e0dd456ad34fe906 Reviewed-on: https://dart-review.googlesource.com/60403 Reviewed-by: Alexander Markov <[email protected]> Commit-Queue: Aart Bik <[email protected]>
1 parent dd8988c commit 2a396d5

File tree

7 files changed

+70
-11
lines changed

7 files changed

+70
-11
lines changed

runtime/vm/compiler/assembler/assembler_arm64.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,7 @@ class Address : public ValueObject {
255255
return kUnsignedWord;
256256
case kTypedDataInt64ArrayCid:
257257
case kTypedDataUint64ArrayCid:
258-
UNREACHABLE();
259-
return kByte;
258+
return kDWord;
260259
case kTypedDataFloat32ArrayCid:
261260
return kSWord;
262261
case kTypedDataFloat64ArrayCid:

runtime/vm/compiler/backend/il_arm64.cc

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,7 @@ Representation LoadIndexedInstr::representation() const {
10471047
case kTypedDataUint32ArrayCid:
10481048
return kUnboxedUint32;
10491049
case kTypedDataInt64ArrayCid:
1050+
case kTypedDataUint64ArrayCid:
10501051
return kUnboxedInt64;
10511052
case kTypedDataFloat32ArrayCid:
10521053
case kTypedDataFloat64ArrayCid:
@@ -1200,7 +1201,8 @@ void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
12001201
}
12011202

12021203
if (representation() == kUnboxedInt64) {
1203-
ASSERT(class_id() == kTypedDataInt64ArrayCid);
1204+
ASSERT(class_id() == kTypedDataInt64ArrayCid ||
1205+
class_id() == kTypedDataUint64ArrayCid);
12041206
Register result = locs()->out(0).reg();
12051207
if (aligned()) {
12061208
__ ldr(result, element_address, kDoubleWord);
@@ -1336,6 +1338,7 @@ Representation StoreIndexedInstr::RequiredInputRepresentation(
13361338
case kTypedDataUint32ArrayCid:
13371339
return kUnboxedUint32;
13381340
case kTypedDataInt64ArrayCid:
1341+
case kTypedDataUint64ArrayCid:
13391342
return kUnboxedInt64;
13401343
case kTypedDataFloat32ArrayCid:
13411344
case kTypedDataFloat64ArrayCid:
@@ -1380,6 +1383,8 @@ LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone,
13801383
case kTypedDataUint16ArrayCid:
13811384
case kTypedDataInt32ArrayCid:
13821385
case kTypedDataUint32ArrayCid:
1386+
case kTypedDataInt64ArrayCid:
1387+
case kTypedDataUint64ArrayCid:
13831388
locs->set_in(2, Location::RequiresRegister());
13841389
break;
13851390
case kTypedDataFloat32ArrayCid:
@@ -1508,6 +1513,16 @@ void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
15081513
}
15091514
break;
15101515
}
1516+
case kTypedDataInt64ArrayCid:
1517+
case kTypedDataUint64ArrayCid: {
1518+
const Register value = locs()->in(2).reg();
1519+
if (aligned()) {
1520+
__ str(value, element_address, kDoubleWord);
1521+
} else {
1522+
__ StoreUnaligned(value, address, scratch, kDoubleWord);
1523+
}
1524+
break;
1525+
}
15111526
case kTypedDataFloat32ArrayCid: {
15121527
const VRegister value_reg = locs()->in(2).fpu_reg();
15131528
if (aligned()) {

runtime/vm/compiler/backend/il_x64.cc

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,8 +1093,8 @@ CompileType LoadIndexedInstr::ComputeType() const {
10931093
case kTypedDataInt32ArrayCid:
10941094
case kTypedDataUint32ArrayCid:
10951095
return CompileType::FromCid(kSmiCid);
1096-
10971096
case kTypedDataInt64ArrayCid:
1097+
case kTypedDataUint64ArrayCid:
10981098
return CompileType::Int();
10991099

11001100
default:
@@ -1124,6 +1124,7 @@ Representation LoadIndexedInstr::representation() const {
11241124
case kTypedDataUint32ArrayCid:
11251125
return kUnboxedUint32;
11261126
case kTypedDataInt64ArrayCid:
1127+
case kTypedDataUint64ArrayCid:
11271128
return kUnboxedInt64;
11281129
case kTypedDataFloat32ArrayCid:
11291130
case kTypedDataFloat64ArrayCid:
@@ -1229,7 +1230,8 @@ void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
12291230
}
12301231

12311232
if (representation() == kUnboxedInt64) {
1232-
ASSERT(class_id() == kTypedDataInt64ArrayCid);
1233+
ASSERT(class_id() == kTypedDataInt64ArrayCid ||
1234+
class_id() == kTypedDataUint64ArrayCid);
12331235
if ((index_scale() == 1) && index.IsRegister()) {
12341236
__ SmiUntag(index.reg());
12351237
}
@@ -1361,6 +1363,7 @@ Representation StoreIndexedInstr::RequiredInputRepresentation(
13611363
case kTypedDataUint32ArrayCid:
13621364
return kUnboxedUint32;
13631365
case kTypedDataInt64ArrayCid:
1366+
case kTypedDataUint64ArrayCid:
13641367
return kUnboxedInt64;
13651368
case kTypedDataFloat32ArrayCid:
13661369
case kTypedDataFloat64ArrayCid:
@@ -1421,6 +1424,7 @@ LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone,
14211424
case kTypedDataInt32ArrayCid:
14221425
case kTypedDataUint32ArrayCid:
14231426
case kTypedDataInt64ArrayCid:
1427+
case kTypedDataUint64ArrayCid:
14241428
locs->set_in(2, Location::RequiresRegister());
14251429
break;
14261430
case kTypedDataFloat32ArrayCid:
@@ -1525,7 +1529,8 @@ void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
15251529
__ movl(element_address, value);
15261530
break;
15271531
}
1528-
case kTypedDataInt64ArrayCid: {
1532+
case kTypedDataInt64ArrayCid:
1533+
case kTypedDataUint64ArrayCid: {
15291534
Register value = locs()->in(2).reg();
15301535
__ movq(element_address, value);
15311536
break;

runtime/vm/compiler/backend/inliner.cc

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3104,6 +3104,7 @@ bool FlowGraphInliner::TryReplaceInstanceCallWithInline(
31043104
}
31053105
// Replace all uses of this definition with the result.
31063106
if (call->HasUses()) {
3107+
ASSERT(last->IsDefinition());
31073108
call->ReplaceUsesWith(last->AsDefinition());
31083109
}
31093110
// Finally insert the sequence other definition in place of this one in the
@@ -3359,17 +3360,19 @@ bool FlowGraphInliner::TryInlineRecognizedMethod(
33593360
can_speculate);
33603361
case MethodRecognizer::kInt32ArrayGetIndexed:
33613362
case MethodRecognizer::kUint32ArrayGetIndexed:
3362-
if (!CanUnboxInt32()) return false;
3363+
if (!CanUnboxInt32()) {
3364+
return false;
3365+
}
33633366
return InlineGetIndexed(flow_graph, kind, call, receiver, entry, last,
33643367
can_speculate);
3365-
33663368
case MethodRecognizer::kInt64ArrayGetIndexed:
33673369
if (!ShouldInlineInt64ArrayOps()) {
33683370
return false;
33693371
}
33703372
return InlineGetIndexed(flow_graph, kind, call, receiver, entry, last,
33713373
can_speculate);
3372-
3374+
case MethodRecognizer::kUint64ArrayGetIndexed:
3375+
break; // TODO(ajcbik): do this too?
33733376
default:
33743377
break;
33753378
}
@@ -3416,6 +3419,8 @@ bool FlowGraphInliner::TryInlineRecognizedMethod(
34163419
}
34173420
return InlineSetIndexed(flow_graph, kind, target, call, receiver,
34183421
token_pos, /* value_check = */ NULL, entry, last);
3422+
case MethodRecognizer::kUint64ArraySetIndexed:
3423+
return false; // TODO(ajcbik): do this too?
34193424
case MethodRecognizer::kFloat32ArraySetIndexed:
34203425
case MethodRecognizer::kFloat64ArraySetIndexed: {
34213426
if (!CanUnboxDouble()) {

runtime/vm/compiler/intrinsifier.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,22 @@ bool Intrinsifier::CanIntrinsify(const Function& function) {
5454
}
5555
return false;
5656
}
57+
switch (function.recognized_kind()) {
58+
case MethodRecognizer::kInt64ArrayGetIndexed:
59+
case MethodRecognizer::kInt64ArraySetIndexed:
60+
case MethodRecognizer::kUint64ArrayGetIndexed:
61+
case MethodRecognizer::kUint64ArraySetIndexed:
62+
// TODO(ajcbik): consider 32-bit as well.
63+
if (kBitsPerWord == 64 && FlowGraphCompiler::SupportsUnboxedInt64()) {
64+
break;
65+
}
66+
if (FLAG_trace_intrinsifier) {
67+
THR_Print("No, 64-bit int intrinsic on 32-bit platform.\n");
68+
}
69+
return false;
70+
default:
71+
break;
72+
}
5773
if (FLAG_trace_intrinsifier) {
5874
THR_Print("Yes.\n");
5975
}
@@ -523,6 +539,11 @@ static bool IntrinsifyArrayGetIndexed(FlowGraph* flow_graph,
523539
case kTypedDataUint16ArrayCid:
524540
// Nothing to do.
525541
break;
542+
case kTypedDataInt64ArrayCid:
543+
case kTypedDataUint64ArrayCid:
544+
result = builder.AddDefinition(
545+
BoxInstr::Create(kUnboxedInt64, new Value(result)));
546+
break;
526547
default:
527548
UNREACHABLE();
528549
break;
@@ -572,6 +593,12 @@ static bool IntrinsifyArraySetIndexed(FlowGraph* flow_graph,
572593
value = builder.AddUnboxInstr(kUnboxedUint32, new Value(value),
573594
/* is_checked = */ false);
574595
break;
596+
case kTypedDataInt64ArrayCid:
597+
case kTypedDataUint64ArrayCid:
598+
value = builder.AddUnboxInstr(kUnboxedInt64, new Value(value),
599+
/* is_checked = */ false);
600+
break;
601+
575602
case kTypedDataFloat32ArrayCid:
576603
case kTypedDataFloat64ArrayCid:
577604
case kTypedDataFloat32x4ArrayCid:
@@ -660,6 +687,8 @@ DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Int16Array)
660687
DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Uint16Array)
661688
DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Int32Array)
662689
DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Uint32Array)
690+
DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Int64Array)
691+
DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Uint64Array)
663692

664693
#undef DEFINE_ARRAY_GETTER_SETTER_INTRINSICS
665694
#undef DEFINE_ARRAY_GETTER_INTRINSIC

runtime/vm/compiler/method_recognizer.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ intptr_t MethodRecognizer::MethodKindToReceiverCid(Kind kind) {
9797
case kInt64ArraySetIndexed:
9898
return kTypedDataInt64ArrayCid;
9999

100+
case kUint64ArrayGetIndexed:
101+
case kUint64ArraySetIndexed:
102+
return kTypedDataUint64ArrayCid;
103+
100104
case kFloat32x4ArrayGetIndexed:
101105
case kFloat32x4ArraySetIndexed:
102106
return kTypedDataFloat32x4ArrayCid;

runtime/vm/compiler/method_recognizer.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,6 @@ namespace dart {
118118
V(_Int32x4, withFlagY, Int32x4WithFlagY, Int32x4, 0x6485a9c4) \
119119
V(_Int32x4, withFlagZ, Int32x4WithFlagZ, Int32x4, 0x267acdfa) \
120120
V(_Int32x4, withFlagW, Int32x4WithFlagW, Int32x4, 0x345ac675) \
121-
V(_Int64List, [], Int64ArrayGetIndexed, Dynamic, 0x51eafb97) \
122-
V(_Int64List, []=, Int64ArraySetIndexed, Dynamic, 0x376181fb) \
123121
V(_HashVMBase, get:_index, LinkedHashMap_getIndex, TypedDataUint32Array, \
124122
0x02477157) \
125123
V(_HashVMBase, set:_index, LinkedHashMap_setIndex, Dynamic, 0x4fc8d5e0) \
@@ -299,6 +297,10 @@ namespace dart {
299297
V(_Int32List, []=, Int32ArraySetIndexed, Dynamic, 0x1adf9823) \
300298
V(_Uint32List, [], Uint32ArrayGetIndexed, Dynamic, 0x188658ce) \
301299
V(_Uint32List, []=, Uint32ArraySetIndexed, Dynamic, 0x01f51a79) \
300+
V(_Int64List, [], Int64ArrayGetIndexed, Dynamic, 0x51eafb97) \
301+
V(_Int64List, []=, Int64ArraySetIndexed, Dynamic, 0x376181fb) \
302+
V(_Uint64List, [], Uint64ArrayGetIndexed, Dynamic, 0x4b2a1ba2) \
303+
V(_Uint64List, []=, Uint64ArraySetIndexed, Dynamic, 0x5f881bd4) \
302304
V(_Float64List, [], Float64ArrayGetIndexed, Double, 0x0a714486) \
303305
V(_Float64List, []=, Float64ArraySetIndexed, Dynamic, 0x04937367) \
304306
V(_Float32List, [], Float32ArrayGetIndexed, Double, 0x5ade301f) \

0 commit comments

Comments
 (0)