Skip to content

Commit a7e2dce

Browse files
alexmarkovCommit Queue
authored andcommitted
[vm] Implement typed data view GetIndexed in flow graph builder
Typed data view 'operator []' is now implemented in the flow graph builder. This unifies all typed data GetIndexed operations and removes unnecessary address calculations. TEST=ci Change-Id: I8d2ca6e7c7bf18b2590536a643f92cad5beb6d95 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/361283 Reviewed-by: Tess Strickland <[email protected]> Commit-Queue: Alexander Markov <[email protected]> Reviewed-by: Slava Egorov <[email protected]>
1 parent af87689 commit a7e2dce

File tree

7 files changed

+154
-310
lines changed

7 files changed

+154
-310
lines changed

runtime/tests/vm/dart/typed_list_index_checkbound_il_test.dart

Lines changed: 15 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ int retrieveFromView(Int8List src, int n) => src[n];
1717

1818
@pragma('vm:never-inline')
1919
@pragma('vm:testing:print-flow-graph')
20-
int retrieveFromBase(Int8List src, int n) => src[n];
20+
int retrieveFromInternal(Int8List src, int n) => src[n];
2121

2222
@pragma('vm:never-inline')
2323
@pragma('vm:testing:print-flow-graph')
2424
int retrieveFromExternal(Int8List src, int n) => src[n];
2525

26-
void matchIL$retrieveFromView(FlowGraph graph) {
26+
void matchILRetrieveFromNonInternal(FlowGraph graph) {
2727
graph.match([
2828
match.block('Graph'),
2929
match.block('Function', [
@@ -37,49 +37,27 @@ void matchIL$retrieveFromView(FlowGraph graph) {
3737
'unboxed_len' << match.UnboxInt64('len'),
3838
match.GenericCheckBound('unboxed_len', 'n'),
3939
],
40-
'typed_data' << match.LoadField('src', slot: 'TypedDataView.typed_data'),
41-
'boxed_offset' <<
42-
match.LoadField('src', slot: 'TypedDataView.offset_in_bytes'),
43-
'offset' << match.UnboxInt64('boxed_offset'),
44-
'index' << match.BinaryInt64Op('offset', 'n', op_kind: '+'),
45-
if (is32BitConfiguration) ...[
46-
'boxed_index' << match.BoxInt64('index'),
47-
],
48-
'data' << match.LoadField('typed_data', slot: 'PointerBase.data'),
40+
'data' << match.LoadField('src', slot: 'PointerBase.data'),
4941
if (is32BitConfiguration) ...[
50-
'retval32' << match.LoadIndexed('data', 'boxed_index'),
42+
'retval32' << match.LoadIndexed('data', 'boxed_n'),
5143
'retval' << match.IntConverter('retval32', from: 'int32', to: 'int64'),
5244
] else ...[
53-
'retval' << match.LoadIndexed('data', 'index'),
45+
'retval' << match.LoadIndexed('data', 'n'),
5446
],
5547
match.DartReturn('retval'),
5648
]),
5749
]);
5850
}
5951

60-
void matchIL$retrieveFromBase(FlowGraph graph) {
61-
graph.match([
62-
match.block('Graph'),
63-
match.block('Function', [
64-
'src' << match.Parameter(index: 0),
65-
'n' << match.Parameter(index: 1),
66-
'len' << match.LoadField('src', slot: 'TypedDataBase.length'),
67-
if (is32BitConfiguration) ...[
68-
'boxed_n' << match.BoxInt64('n'),
69-
match.GenericCheckBound('len', 'boxed_n'),
70-
'retval32' << match.LoadIndexed('src', 'boxed_n'),
71-
'retval' << match.IntConverter('retval32', from: 'int32', to: 'int64'),
72-
] else ...[
73-
'unboxed_len' << match.UnboxInt64('len'),
74-
match.GenericCheckBound('unboxed_len', 'n'),
75-
'retval' << match.LoadIndexed('src', 'n'),
76-
],
77-
match.DartReturn('retval'),
78-
]),
79-
]);
52+
void matchIL$retrieveFromView(FlowGraph graph) {
53+
matchILRetrieveFromNonInternal(graph);
8054
}
8155

8256
void matchIL$retrieveFromExternal(FlowGraph graph) {
57+
matchILRetrieveFromNonInternal(graph);
58+
}
59+
60+
void matchIL$retrieveFromInternal(FlowGraph graph) {
8361
graph.match([
8462
match.block('Graph'),
8563
match.block('Function', [
@@ -89,16 +67,12 @@ void matchIL$retrieveFromExternal(FlowGraph graph) {
8967
if (is32BitConfiguration) ...[
9068
'boxed_n' << match.BoxInt64('n'),
9169
match.GenericCheckBound('len', 'boxed_n'),
70+
'retval32' << match.LoadIndexed('src', 'boxed_n'),
71+
'retval' << match.IntConverter('retval32', from: 'int32', to: 'int64'),
9272
] else ...[
9373
'unboxed_len' << match.UnboxInt64('len'),
9474
match.GenericCheckBound('unboxed_len', 'n'),
95-
],
96-
'data' << match.LoadField('src', slot: 'PointerBase.data'),
97-
if (is32BitConfiguration) ...[
98-
'retval32' << match.LoadIndexed('data', 'boxed_n'),
99-
'retval' << match.IntConverter('retval32', from: 'int32', to: 'int64'),
100-
] else ...[
101-
'retval' << match.LoadIndexed('data', 'n'),
75+
'retval' << match.LoadIndexed('src', 'n'),
10276
],
10377
match.DartReturn('retval'),
10478
]),
@@ -108,7 +82,7 @@ void matchIL$retrieveFromExternal(FlowGraph graph) {
10882
void main(List<String> args) {
10983
final n = args.isEmpty ? 0 : int.parse(args.first);
11084
final list = Int8List.fromList([1, 2, 3, 4]);
111-
print(retrieveFromBase(list, n));
85+
print(retrieveFromInternal(list, n));
11286
print(retrieveFromView(Int8List.sublistView(list), n));
11387
if (!isSimulator) {
11488
using((arena) {

runtime/vm/compiler/backend/redundancy_elimination.cc

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,31 +1110,41 @@ class AliasedSet : public ZoneAllocated {
11101110
} else if (UseIsARedefinition(use) &&
11111111
AnyUseCreatesAlias(instr->Cast<Definition>())) {
11121112
return true;
1113-
} else if ((instr->IsStoreField() &&
1114-
(use->use_index() != StoreFieldInstr::kInstancePos))) {
1115-
ASSERT(use->use_index() == StoreFieldInstr::kValuePos);
1116-
// If we store this value into an object that is not aliased itself
1117-
// and we never load again then the store does not create an alias.
1113+
} else if (instr->IsStoreField()) {
11181114
StoreFieldInstr* store = instr->AsStoreField();
1119-
Definition* instance =
1120-
store->instance()->definition()->OriginalDefinition();
1121-
if (Place::IsAllocation(instance) &&
1122-
!instance->Identity().IsAliased()) {
1123-
bool is_load, is_store;
1124-
Place store_place(instr, &is_load, &is_store);
1125-
1126-
if (!HasLoadsFromPlace(instance, &store_place)) {
1127-
// No loads found that match this store. If it is yet unknown if
1128-
// the object is not aliased then optimistically assume this but
1129-
// add it to the worklist to check its uses transitively.
1130-
if (instance->Identity().IsUnknown()) {
1131-
instance->SetIdentity(AliasIdentity::NotAliased());
1132-
aliasing_worklist_.Add(instance);
1115+
1116+
if (store->slot().kind() == Slot::Kind::kTypedDataView_typed_data) {
1117+
// Initialization of TypedDataView.typed_data field creates
1118+
// aliasing between the view and original typed data,
1119+
// as the same data can now be accessed via both typed data
1120+
// view and the original typed data.
1121+
return true;
1122+
}
1123+
1124+
if (use->use_index() != StoreFieldInstr::kInstancePos) {
1125+
ASSERT(use->use_index() == StoreFieldInstr::kValuePos);
1126+
// If we store this value into an object that is not aliased itself
1127+
// and we never load again then the store does not create an alias.
1128+
Definition* instance =
1129+
store->instance()->definition()->OriginalDefinition();
1130+
if (Place::IsAllocation(instance) &&
1131+
!instance->Identity().IsAliased()) {
1132+
bool is_load, is_store;
1133+
Place store_place(instr, &is_load, &is_store);
1134+
1135+
if (!HasLoadsFromPlace(instance, &store_place)) {
1136+
// No loads found that match this store. If it is yet unknown if
1137+
// the object is not aliased then optimistically assume this but
1138+
// add it to the worklist to check its uses transitively.
1139+
if (instance->Identity().IsUnknown()) {
1140+
instance->SetIdentity(AliasIdentity::NotAliased());
1141+
aliasing_worklist_.Add(instance);
1142+
}
1143+
continue;
11331144
}
1134-
continue;
11351145
}
1146+
return true;
11361147
}
1137-
return true;
11381148
} else if (auto* const alloc = instr->AsAllocation()) {
11391149
// Treat inputs to an allocation instruction exactly as if they were
11401150
// manually stored using a StoreField instruction.

runtime/vm/compiler/frontend/kernel_to_il.cc

Lines changed: 19 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -960,36 +960,17 @@ bool FlowGraphBuilder::IsRecognizedMethodForFlowGraph(
960960
const MethodRecognizer::Kind kind = function.recognized_kind();
961961

962962
switch (kind) {
963+
#define TYPED_DATA_GET_INDEXED_CASES(clazz) \
964+
case MethodRecognizer::k##clazz##ArrayGetIndexed: \
965+
FALL_THROUGH; \
966+
case MethodRecognizer::kExternal##clazz##ArrayGetIndexed: \
967+
FALL_THROUGH; \
968+
case MethodRecognizer::k##clazz##ArrayViewGetIndexed: \
969+
FALL_THROUGH;
970+
DART_CLASS_LIST_TYPED_DATA(TYPED_DATA_GET_INDEXED_CASES);
971+
#undef TYPED_DATA_GET_INDEXED_CASES
963972
case MethodRecognizer::kObjectArrayGetIndexed:
964973
case MethodRecognizer::kGrowableArrayGetIndexed:
965-
case MethodRecognizer::kInt8ArrayGetIndexed:
966-
case MethodRecognizer::kExternalInt8ArrayGetIndexed:
967-
case MethodRecognizer::kUint8ArrayGetIndexed:
968-
case MethodRecognizer::kExternalUint8ArrayGetIndexed:
969-
case MethodRecognizer::kUint8ClampedArrayGetIndexed:
970-
case MethodRecognizer::kExternalUint8ClampedArrayGetIndexed:
971-
case MethodRecognizer::kInt16ArrayGetIndexed:
972-
case MethodRecognizer::kExternalInt16ArrayGetIndexed:
973-
case MethodRecognizer::kUint16ArrayGetIndexed:
974-
case MethodRecognizer::kExternalUint16ArrayGetIndexed:
975-
case MethodRecognizer::kInt32ArrayGetIndexed:
976-
case MethodRecognizer::kExternalInt32ArrayGetIndexed:
977-
case MethodRecognizer::kUint32ArrayGetIndexed:
978-
case MethodRecognizer::kExternalUint32ArrayGetIndexed:
979-
case MethodRecognizer::kInt64ArrayGetIndexed:
980-
case MethodRecognizer::kExternalInt64ArrayGetIndexed:
981-
case MethodRecognizer::kUint64ArrayGetIndexed:
982-
case MethodRecognizer::kExternalUint64ArrayGetIndexed:
983-
case MethodRecognizer::kFloat32ArrayGetIndexed:
984-
case MethodRecognizer::kExternalFloat32ArrayGetIndexed:
985-
case MethodRecognizer::kFloat64ArrayGetIndexed:
986-
case MethodRecognizer::kExternalFloat64ArrayGetIndexed:
987-
case MethodRecognizer::kFloat32x4ArrayGetIndexed:
988-
case MethodRecognizer::kExternalFloat32x4ArrayGetIndexed:
989-
case MethodRecognizer::kFloat64x2ArrayGetIndexed:
990-
case MethodRecognizer::kExternalFloat64x2ArrayGetIndexed:
991-
case MethodRecognizer::kInt32x4ArrayGetIndexed:
992-
case MethodRecognizer::kExternalInt32x4ArrayGetIndexed:
993974
case MethodRecognizer::kRecord_fieldAt:
994975
case MethodRecognizer::kRecord_fieldNames:
995976
case MethodRecognizer::kRecord_numFields:
@@ -1214,36 +1195,17 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfRecognizedMethod(
12141195

12151196
const MethodRecognizer::Kind kind = function.recognized_kind();
12161197
switch (kind) {
1198+
#define TYPED_DATA_GET_INDEXED_CASES(clazz) \
1199+
case MethodRecognizer::k##clazz##ArrayGetIndexed: \
1200+
FALL_THROUGH; \
1201+
case MethodRecognizer::kExternal##clazz##ArrayGetIndexed: \
1202+
FALL_THROUGH; \
1203+
case MethodRecognizer::k##clazz##ArrayViewGetIndexed: \
1204+
FALL_THROUGH;
1205+
DART_CLASS_LIST_TYPED_DATA(TYPED_DATA_GET_INDEXED_CASES);
1206+
#undef TYPED_DATA_GET_INDEXED_CASES
12171207
case MethodRecognizer::kObjectArrayGetIndexed:
1218-
case MethodRecognizer::kGrowableArrayGetIndexed:
1219-
case MethodRecognizer::kInt8ArrayGetIndexed:
1220-
case MethodRecognizer::kExternalInt8ArrayGetIndexed:
1221-
case MethodRecognizer::kUint8ArrayGetIndexed:
1222-
case MethodRecognizer::kExternalUint8ArrayGetIndexed:
1223-
case MethodRecognizer::kUint8ClampedArrayGetIndexed:
1224-
case MethodRecognizer::kExternalUint8ClampedArrayGetIndexed:
1225-
case MethodRecognizer::kInt16ArrayGetIndexed:
1226-
case MethodRecognizer::kExternalInt16ArrayGetIndexed:
1227-
case MethodRecognizer::kUint16ArrayGetIndexed:
1228-
case MethodRecognizer::kExternalUint16ArrayGetIndexed:
1229-
case MethodRecognizer::kInt32ArrayGetIndexed:
1230-
case MethodRecognizer::kExternalInt32ArrayGetIndexed:
1231-
case MethodRecognizer::kUint32ArrayGetIndexed:
1232-
case MethodRecognizer::kExternalUint32ArrayGetIndexed:
1233-
case MethodRecognizer::kInt64ArrayGetIndexed:
1234-
case MethodRecognizer::kExternalInt64ArrayGetIndexed:
1235-
case MethodRecognizer::kUint64ArrayGetIndexed:
1236-
case MethodRecognizer::kExternalUint64ArrayGetIndexed:
1237-
case MethodRecognizer::kFloat32ArrayGetIndexed:
1238-
case MethodRecognizer::kExternalFloat32ArrayGetIndexed:
1239-
case MethodRecognizer::kFloat64ArrayGetIndexed:
1240-
case MethodRecognizer::kExternalFloat64ArrayGetIndexed:
1241-
case MethodRecognizer::kFloat32x4ArrayGetIndexed:
1242-
case MethodRecognizer::kExternalFloat32x4ArrayGetIndexed:
1243-
case MethodRecognizer::kFloat64x2ArrayGetIndexed:
1244-
case MethodRecognizer::kExternalFloat64x2ArrayGetIndexed:
1245-
case MethodRecognizer::kInt32x4ArrayGetIndexed:
1246-
case MethodRecognizer::kExternalInt32x4ArrayGetIndexed: {
1208+
case MethodRecognizer::kGrowableArrayGetIndexed: {
12471209
ASSERT_EQUAL(function.NumParameters(), 2);
12481210
intptr_t array_cid = MethodRecognizer::MethodKindToReceiverCid(kind);
12491211
const Representation elem_rep =

runtime/vm/compiler/method_recognizer.cc

Lines changed: 11 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -104,106 +104,24 @@ intptr_t MethodRecognizer::MethodKindToReceiverCid(Kind kind) {
104104
case kGrowableArraySetIndexedUnchecked:
105105
return kGrowableObjectArrayCid;
106106

107-
case kFloat32ArrayGetIndexed:
108-
case kFloat32ArraySetIndexed:
109-
return kTypedDataFloat32ArrayCid;
107+
#define TYPED_DATA_GET_SET_INDEXED_CASES(clazz) \
108+
case k##clazz##ArrayGetIndexed: \
109+
case k##clazz##ArraySetIndexed: \
110+
return kTypedData##clazz##ArrayCid; \
111+
case kExternal##clazz##ArrayGetIndexed: \
112+
return kExternalTypedData##clazz##ArrayCid; \
113+
case k##clazz##ArrayViewGetIndexed: \
114+
return kTypedData##clazz##ArrayViewCid;
115+
116+
DART_CLASS_LIST_TYPED_DATA(TYPED_DATA_GET_SET_INDEXED_CASES);
117+
#undef TYPED_DATA_GET_SET_INDEXED_CASES
110118

111-
case kExternalFloat32ArrayGetIndexed:
112-
return kExternalTypedDataFloat32ArrayCid;
113-
114-
case kFloat64ArrayGetIndexed:
115-
case kFloat64ArraySetIndexed:
116-
return kTypedDataFloat64ArrayCid;
117-
118-
case kExternalFloat64ArrayGetIndexed:
119-
return kExternalTypedDataFloat64ArrayCid;
120-
121-
case kInt8ArrayGetIndexed:
122-
case kInt8ArraySetIndexed:
123-
return kTypedDataInt8ArrayCid;
124-
125-
case kExternalInt8ArrayGetIndexed:
126-
return kExternalTypedDataInt8ArrayCid;
127-
128-
case kUint8ArrayGetIndexed:
129-
case kUint8ArraySetIndexed:
130-
return kTypedDataUint8ArrayCid;
131-
132-
case kUint8ClampedArrayGetIndexed:
133-
case kUint8ClampedArraySetIndexed:
134-
return kTypedDataUint8ClampedArrayCid;
135-
136-
case kExternalUint8ArrayGetIndexed:
137119
case kExternalUint8ArraySetIndexed:
138120
return kExternalTypedDataUint8ArrayCid;
139121

140-
case kExternalUint8ClampedArrayGetIndexed:
141122
case kExternalUint8ClampedArraySetIndexed:
142123
return kExternalTypedDataUint8ClampedArrayCid;
143124

144-
case kInt16ArrayGetIndexed:
145-
case kInt16ArraySetIndexed:
146-
return kTypedDataInt16ArrayCid;
147-
148-
case kExternalInt16ArrayGetIndexed:
149-
return kExternalTypedDataInt16ArrayCid;
150-
151-
case kUint16ArrayGetIndexed:
152-
case kUint16ArraySetIndexed:
153-
return kTypedDataUint16ArrayCid;
154-
155-
case kExternalUint16ArrayGetIndexed:
156-
return kExternalTypedDataUint16ArrayCid;
157-
158-
case kInt32ArrayGetIndexed:
159-
case kInt32ArraySetIndexed:
160-
return kTypedDataInt32ArrayCid;
161-
162-
case kExternalInt32ArrayGetIndexed:
163-
return kExternalTypedDataInt32ArrayCid;
164-
165-
case kUint32ArrayGetIndexed:
166-
case kUint32ArraySetIndexed:
167-
return kTypedDataUint32ArrayCid;
168-
169-
case kExternalUint32ArrayGetIndexed:
170-
return kExternalTypedDataUint32ArrayCid;
171-
172-
case kInt64ArrayGetIndexed:
173-
case kInt64ArraySetIndexed:
174-
return kTypedDataInt64ArrayCid;
175-
176-
case kExternalInt64ArrayGetIndexed:
177-
return kExternalTypedDataInt64ArrayCid;
178-
179-
case kUint64ArrayGetIndexed:
180-
case kUint64ArraySetIndexed:
181-
return kTypedDataUint64ArrayCid;
182-
183-
case kExternalUint64ArrayGetIndexed:
184-
return kExternalTypedDataUint64ArrayCid;
185-
186-
case kFloat32x4ArrayGetIndexed:
187-
case kFloat32x4ArraySetIndexed:
188-
return kTypedDataFloat32x4ArrayCid;
189-
190-
case kExternalFloat32x4ArrayGetIndexed:
191-
return kExternalTypedDataFloat32x4ArrayCid;
192-
193-
case kInt32x4ArrayGetIndexed:
194-
case kInt32x4ArraySetIndexed:
195-
return kTypedDataInt32x4ArrayCid;
196-
197-
case kExternalInt32x4ArrayGetIndexed:
198-
return kExternalTypedDataInt32x4ArrayCid;
199-
200-
case kFloat64x2ArrayGetIndexed:
201-
case kFloat64x2ArraySetIndexed:
202-
return kTypedDataFloat64x2ArrayCid;
203-
204-
case kExternalFloat64x2ArrayGetIndexed:
205-
return kExternalTypedDataFloat64x2ArrayCid;
206-
207125
default:
208126
break;
209127
}

0 commit comments

Comments
 (0)