Skip to content

Commit 6249b7e

Browse files
mralephCommit Queue
authored and
Commit Queue
committed
[vm/compiler] Clean up typed data stores
Implementation of stores and their inlinings had some stuff left over their since Dart 1: * No need to insert null-checks (in sound null-safety mode). * Since Dart 2 there is no need to insert (speculative) cid checks. Inputs are guaranteed to be a value of a supported implementation type. Inserting narrow speculative checks for Smis is actually leads to worse code in JIT. * There is no need to convert incomming integer values to smaller representation - the store will take care of it. This was left over from Dart 1 times when incomming integer could be _Bigint. TEST=existing tests Cq-Include-Trybots: luci.dart.try:vm-aot-linux-release-simarm_x64-try,vm-aot-linux-release-arm64-try,vm-aot-linux-release-x64-try,vm-aot-mac-product-arm64-try,vm-aot-linux-product-x64-try,vm-aot-linux-debug-x64c-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-simarm_x64-try,vm-aot-linux-debug-simriscv64-try,vm-aot-android-release-arm_x64-try,vm-aot-android-release-arm64c-try Change-Id: I72cdaaecc524f1dccc63825df4f7b71241ab47a0 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/338600 Commit-Queue: Slava Egorov <[email protected]> Reviewed-by: Martin Kustermann <[email protected]>
1 parent 86231e2 commit 6249b7e

File tree

3 files changed

+64
-210
lines changed

3 files changed

+64
-210
lines changed

runtime/vm/compiler/backend/inliner.cc

Lines changed: 40 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -2911,7 +2911,6 @@ static bool InlineSetIndexed(FlowGraph* flow_graph,
29112911
Instruction* call,
29122912
Definition* receiver,
29132913
const InstructionSource& source,
2914-
const Cids* value_check,
29152914
FlowGraphInliner::ExactnessInfo* exactness,
29162915
GraphEntryInstr* graph_entry,
29172916
FunctionEntryInstr** entry,
@@ -3050,16 +3049,6 @@ static bool InlineSetIndexed(FlowGraph* flow_graph,
30503049
array_cid == kExternalTypedDataUint8ArrayCid ||
30513050
array_cid == kExternalTypedDataUint8ClampedArrayCid;
30523051

3053-
if (value_check != nullptr) {
3054-
// No store barrier needed because checked value is a smi, an unboxed mint,
3055-
// an unboxed double, an unboxed Float32x4, or unboxed Int32x4.
3056-
needs_store_barrier = kNoStoreBarrier;
3057-
Instruction* check = flow_graph->CreateCheckClass(
3058-
stored_value, *value_check, call->deopt_id(), call->source());
3059-
cursor =
3060-
flow_graph->AppendTo(cursor, check, call->env(), FlowGraph::kEffect);
3061-
}
3062-
30633052
if (array_cid == kTypedDataFloat32ArrayCid) {
30643053
stored_value = new (Z)
30653054
DoubleToFloatInstr(new (Z) Value(stored_value), call->deopt_id());
@@ -3339,110 +3328,16 @@ static bool InlineByteArrayBaseStore(FlowGraph* flow_graph,
33393328
(*entry)->InheritDeoptTarget(Z, call);
33403329
Instruction* cursor = *entry;
33413330

3342-
// Prepare additional checks. In AOT Dart2, we use an explicit null check and
3343-
// non-speculative unboxing for most value types.
3344-
Cids* value_check = nullptr;
3345-
bool needs_null_check = false;
3346-
switch (view_cid) {
3347-
case kTypedDataInt8ArrayCid:
3348-
case kTypedDataUint8ArrayCid:
3349-
case kTypedDataUint8ClampedArrayCid:
3350-
case kExternalTypedDataUint8ArrayCid:
3351-
case kExternalTypedDataUint8ClampedArrayCid:
3352-
case kTypedDataInt16ArrayCid:
3353-
case kTypedDataUint16ArrayCid: {
3354-
if (CompilerState::Current().is_aot()) {
3355-
needs_null_check = true;
3356-
} else {
3357-
// Check that value is always smi.
3358-
value_check = Cids::CreateMonomorphic(Z, kSmiCid);
3359-
}
3360-
break;
3361-
}
3362-
case kTypedDataInt32ArrayCid:
3363-
case kTypedDataUint32ArrayCid:
3364-
if (CompilerState::Current().is_aot()) {
3365-
needs_null_check = true;
3366-
} else {
3367-
// On 64-bit platforms assume that stored value is always a smi.
3368-
if (compiler::target::kSmiBits >= 32) {
3369-
value_check = Cids::CreateMonomorphic(Z, kSmiCid);
3370-
}
3371-
}
3372-
break;
3373-
case kTypedDataFloat32ArrayCid:
3374-
case kTypedDataFloat64ArrayCid: {
3375-
// Check that value is always double.
3376-
if (CompilerState::Current().is_aot()) {
3377-
needs_null_check = true;
3378-
} else {
3379-
value_check = Cids::CreateMonomorphic(Z, kDoubleCid);
3380-
}
3381-
break;
3382-
}
3383-
case kTypedDataInt32x4ArrayCid: {
3384-
// Check that value is always Int32x4.
3385-
value_check = Cids::CreateMonomorphic(Z, kInt32x4Cid);
3386-
break;
3387-
}
3388-
case kTypedDataFloat32x4ArrayCid: {
3389-
// Check that value is always Float32x4.
3390-
value_check = Cids::CreateMonomorphic(Z, kFloat32x4Cid);
3391-
break;
3392-
}
3393-
case kTypedDataFloat64x2ArrayCid: {
3394-
// Check that value is always Float64x2.
3395-
value_check = Cids::CreateMonomorphic(Z, kFloat64x2Cid);
3396-
break;
3397-
}
3398-
case kTypedDataInt64ArrayCid:
3399-
case kTypedDataUint64ArrayCid:
3400-
// StoreIndexedInstr takes unboxed int64, so value is
3401-
// checked when unboxing. In AOT, we use an
3402-
// explicit null check and non-speculative unboxing.
3403-
needs_null_check = CompilerState::Current().is_aot();
3404-
break;
3405-
default:
3406-
// Array cids are already checked in the caller.
3407-
UNREACHABLE();
3408-
}
3409-
34103331
Definition* stored_value = call->ArgumentAt(2);
34113332

3412-
// Handle value check.
3413-
if (value_check != nullptr) {
3414-
Instruction* check = flow_graph->CreateCheckClass(
3415-
stored_value, *value_check, call->deopt_id(), call->source());
3416-
cursor =
3417-
flow_graph->AppendTo(cursor, check, call->env(), FlowGraph::kEffect);
3418-
}
3419-
3420-
// Handle null check.
3421-
if (needs_null_check) {
3333+
// We know that the incomming type matches, but we still need to handle the
3334+
// null check.
3335+
if (!dart::Thread::Current()->isolate_group()->null_safety()) {
34223336
String& name = String::ZoneHandle(Z, target.name());
34233337
Instruction* check = new (Z) CheckNullInstr(
34243338
new (Z) Value(stored_value), name, call->deopt_id(), call->source());
34253339
cursor =
34263340
flow_graph->AppendTo(cursor, check, call->env(), FlowGraph::kEffect);
3427-
// With an explicit null check, a non-speculative unbox suffices.
3428-
switch (view_cid) {
3429-
case kTypedDataFloat32ArrayCid:
3430-
case kTypedDataFloat64ArrayCid:
3431-
stored_value =
3432-
UnboxInstr::Create(kUnboxedDouble, new (Z) Value(stored_value),
3433-
call->deopt_id(), Instruction::kNotSpeculative);
3434-
cursor = flow_graph->AppendTo(cursor, stored_value, call->env(),
3435-
FlowGraph::kValue);
3436-
break;
3437-
case kTypedDataInt64ArrayCid:
3438-
case kTypedDataUint64ArrayCid:
3439-
stored_value = new (Z)
3440-
UnboxInt64Instr(new (Z) Value(stored_value), call->deopt_id(),
3441-
Instruction::kNotSpeculative);
3442-
cursor = flow_graph->AppendTo(cursor, stored_value, call->env(),
3443-
FlowGraph::kValue);
3444-
break;
3445-
}
34463341
}
34473342

34483343
// Handle conversions and special unboxing (to ensure unboxing instructions
@@ -3464,13 +3359,33 @@ static bool InlineByteArrayBaseStore(FlowGraph* flow_graph,
34643359
FlowGraph::kValue);
34653360
break;
34663361
}
3467-
case kTypedDataFloat32ArrayCid: {
3468-
stored_value = new (Z)
3469-
DoubleToFloatInstr(new (Z) Value(stored_value), call->deopt_id());
3470-
cursor = flow_graph->AppendTo(cursor, stored_value, nullptr,
3362+
3363+
case kTypedDataInt64ArrayCid:
3364+
case kTypedDataUint64ArrayCid: {
3365+
stored_value =
3366+
new (Z) UnboxInt64Instr(new (Z) Value(stored_value), call->deopt_id(),
3367+
Instruction::kNotSpeculative);
3368+
cursor = flow_graph->AppendTo(cursor, stored_value, call->env(),
34713369
FlowGraph::kValue);
34723370
break;
34733371
}
3372+
3373+
case kTypedDataFloat32ArrayCid:
3374+
case kTypedDataFloat64ArrayCid: {
3375+
stored_value =
3376+
UnboxInstr::Create(kUnboxedDouble, new (Z) Value(stored_value),
3377+
call->deopt_id(), Instruction::kNotSpeculative);
3378+
cursor = flow_graph->AppendTo(cursor, stored_value, call->env(),
3379+
FlowGraph::kValue);
3380+
if (view_cid == kTypedDataFloat32ArrayCid) {
3381+
stored_value = new (Z)
3382+
DoubleToFloatInstr(new (Z) Value(stored_value), call->deopt_id());
3383+
cursor = flow_graph->AppendTo(cursor, stored_value, call->env(),
3384+
FlowGraph::kValue);
3385+
}
3386+
break;
3387+
}
3388+
34743389
case kTypedDataInt32ArrayCid: {
34753390
stored_value = new (Z)
34763391
UnboxInt32Instr(UnboxInt32Instr::kTruncate,
@@ -4729,72 +4644,50 @@ bool FlowGraphInliner::TryInlineRecognizedMethod(
47294644
}
47304645

47314646
switch (kind) {
4647+
case MethodRecognizer::kUint8ClampedArraySetIndexed:
4648+
case MethodRecognizer::kExternalUint8ClampedArraySetIndexed:
4649+
// These require clamping. Just inline normal body instead which
4650+
// contains necessary clamping code.
4651+
return false;
4652+
47324653
// Recognized []= operators.
47334654
case MethodRecognizer::kObjectArraySetIndexed:
47344655
case MethodRecognizer::kGrowableArraySetIndexed:
47354656
case MethodRecognizer::kObjectArraySetIndexedUnchecked:
47364657
case MethodRecognizer::kGrowableArraySetIndexedUnchecked:
4737-
return InlineSetIndexed(flow_graph, kind, target, call, receiver, source,
4738-
/* value_check = */ nullptr, exactness,
4739-
graph_entry, entry, last, result);
47404658
case MethodRecognizer::kInt8ArraySetIndexed:
47414659
case MethodRecognizer::kUint8ArraySetIndexed:
4742-
case MethodRecognizer::kUint8ClampedArraySetIndexed:
47434660
case MethodRecognizer::kExternalUint8ArraySetIndexed:
4744-
case MethodRecognizer::kExternalUint8ClampedArraySetIndexed:
47454661
case MethodRecognizer::kInt16ArraySetIndexed:
4746-
case MethodRecognizer::kUint16ArraySetIndexed: {
4747-
// Optimistically assume Smi.
4748-
if (ic_data != nullptr &&
4749-
ic_data->HasDeoptReason(ICData::kDeoptCheckSmi)) {
4750-
// Optimistic assumption failed at least once.
4751-
return false;
4752-
}
4753-
Cids* value_check = Cids::CreateMonomorphic(Z, kSmiCid);
4754-
return InlineSetIndexed(flow_graph, kind, target, call, receiver, source,
4755-
value_check, exactness, graph_entry, entry, last,
4756-
result);
4757-
}
4662+
case MethodRecognizer::kUint16ArraySetIndexed:
47584663
case MethodRecognizer::kInt32ArraySetIndexed:
4759-
case MethodRecognizer::kUint32ArraySetIndexed: {
4760-
// Value check not needed for Int32 and Uint32 arrays because they
4761-
// implicitly contain unboxing instructions which check for right type.
4762-
return InlineSetIndexed(flow_graph, kind, target, call, receiver, source,
4763-
/* value_check = */ nullptr, exactness,
4764-
graph_entry, entry, last, result);
4765-
}
4664+
case MethodRecognizer::kUint32ArraySetIndexed:
47664665
case MethodRecognizer::kInt64ArraySetIndexed:
47674666
case MethodRecognizer::kUint64ArraySetIndexed:
47684667
return InlineSetIndexed(flow_graph, kind, target, call, receiver, source,
4769-
/* value_check = */ nullptr, exactness,
4770-
graph_entry, entry, last, result);
4668+
exactness, graph_entry, entry, last, result);
4669+
47714670
case MethodRecognizer::kFloat32ArraySetIndexed:
47724671
case MethodRecognizer::kFloat64ArraySetIndexed: {
47734672
if (!CanUnboxDouble()) {
47744673
return false;
47754674
}
4776-
Cids* value_check = Cids::CreateMonomorphic(Z, kDoubleCid);
47774675
return InlineSetIndexed(flow_graph, kind, target, call, receiver, source,
4778-
value_check, exactness, graph_entry, entry, last,
4779-
result);
4676+
exactness, graph_entry, entry, last, result);
47804677
}
47814678
case MethodRecognizer::kFloat32x4ArraySetIndexed: {
47824679
if (!ShouldInlineSimd()) {
47834680
return false;
47844681
}
4785-
Cids* value_check = Cids::CreateMonomorphic(Z, kFloat32x4Cid);
47864682
return InlineSetIndexed(flow_graph, kind, target, call, receiver, source,
4787-
value_check, exactness, graph_entry, entry, last,
4788-
result);
4683+
exactness, graph_entry, entry, last, result);
47894684
}
47904685
case MethodRecognizer::kFloat64x2ArraySetIndexed: {
47914686
if (!ShouldInlineSimd()) {
47924687
return false;
47934688
}
4794-
Cids* value_check = Cids::CreateMonomorphic(Z, kFloat64x2Cid);
47954689
return InlineSetIndexed(flow_graph, kind, target, call, receiver, source,
4796-
value_check, exactness, graph_entry, entry, last,
4797-
result);
4690+
exactness, graph_entry, entry, last, result);
47984691
}
47994692
case MethodRecognizer::kByteArrayBaseSetInt8:
48004693
return InlineByteArrayBaseStore(flow_graph, target, call, receiver,

runtime/vm/compiler/recognized_methods_list.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ namespace dart {
119119
V(_TypedListBase, _memMove4, TypedData_memMove4, 0xcfe37726) \
120120
V(_TypedListBase, _memMove8, TypedData_memMove8, 0xd1d8e325) \
121121
V(_TypedListBase, _memMove16, TypedData_memMove16, 0x07861cd5) \
122-
V(::, _toClampedUint8, ConvertIntToClampedUint8, 0xd0e522d0) \
123122
V(::, _typedDataIndexCheck, TypedDataIndexCheck, 0xc54f594f) \
124123
V(::, _byteDataByteOffsetCheck, ByteDataByteOffsetCheck, 0x4ae73104) \
125124
V(::, copyRangeFromUint8ListToOneByteString, \
@@ -393,25 +392,25 @@ namespace dart {
393392

394393
#define GRAPH_TYPED_DATA_INTRINSICS_LIST(V) \
395394
V(_Int8List, [], Int8ArrayGetIndexed, 0x7b31eba4) \
396-
V(_Int8List, []=, Int8ArraySetIndexed, 0x02734e41) \
395+
V(_Int8List, []=, Int8ArraySetIndexed, 0x02f7bc29) \
397396
V(_Uint8List, [], Uint8ArrayGetIndexed, 0xe0aa6f64) \
398-
V(_Uint8List, []=, Uint8ArraySetIndexed, 0x4f025a05) \
397+
V(_Uint8List, []=, Uint8ArraySetIndexed, 0xc8fdea5d) \
399398
V(_ExternalUint8Array, [], ExternalUint8ArrayGetIndexed, 0xe0aa6f64) \
400-
V(_ExternalUint8Array, []=, ExternalUint8ArraySetIndexed, 0x4f025a05) \
399+
V(_ExternalUint8Array, []=, ExternalUint8ArraySetIndexed, 0xc8fdea5d) \
401400
V(_Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, 0xe0aa6f64) \
402401
V(_Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, 0x45020fa5) \
403402
V(_ExternalUint8ClampedArray, [], ExternalUint8ClampedArrayGetIndexed, \
404403
0xe0aa6f64) \
405404
V(_ExternalUint8ClampedArray, []=, ExternalUint8ClampedArraySetIndexed, \
406405
0x45020fa5) \
407406
V(_Int16List, [], Int16ArrayGetIndexed, 0x5b304b04) \
408-
V(_Int16List, []=, Int16ArraySetIndexed, 0x92f311cc) \
407+
V(_Int16List, []=, Int16ArraySetIndexed, 0x90aeedef) \
409408
V(_Uint16List, [], Uint16ArrayGetIndexed, 0x3f092704) \
410-
V(_Uint16List, []=, Uint16ArraySetIndexed, 0x7b35b943) \
409+
V(_Uint16List, []=, Uint16ArraySetIndexed, 0x03eecf75) \
411410
V(_Int32List, [], Int32ArrayGetIndexed, 0x5ccdf0a3) \
412-
V(_Int32List, []=, Int32ArraySetIndexed, 0x71278e6b) \
411+
V(_Int32List, []=, Int32ArraySetIndexed, 0x7fb5bb97) \
413412
V(_Uint32List, [], Uint32ArrayGetIndexed, 0xac205643) \
414-
V(_Uint32List, []=, Uint32ArraySetIndexed, 0x5ccb02eb) \
413+
V(_Uint32List, []=, Uint32ArraySetIndexed, 0xc8d82563) \
415414
V(_Int64List, [], Int64ArrayGetIndexed, 0x95964ae3) \
416415
V(_Int64List, []=, Int64ArraySetIndexed, 0xf550bf5d) \
417416
V(_Uint64List, [], Uint64ArrayGetIndexed, 0xd25ab063) \

0 commit comments

Comments
 (0)