OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/load-elimination.h" | 5 #include "src/compiler/load-elimination.h" |
6 #include "src/compiler/access-builder.h" | 6 #include "src/compiler/access-builder.h" |
7 #include "src/compiler/js-graph.h" | 7 #include "src/compiler/js-graph.h" |
8 #include "src/compiler/node.h" | 8 #include "src/compiler/node.h" |
9 #include "src/compiler/simplified-operator.h" | 9 #include "src/compiler/simplified-operator.h" |
10 #include "test/unittests/compiler/graph-reducer-unittest.h" | 10 #include "test/unittests/compiler/graph-reducer-unittest.h" |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 EXPECT_CALL(editor, ReplaceWithValue(load, value, store2, _)); | 118 EXPECT_CALL(editor, ReplaceWithValue(load, value, store2, _)); |
119 Reduction r = load_elimination.Reduce(load); | 119 Reduction r = load_elimination.Reduce(load); |
120 ASSERT_TRUE(r.Changed()); | 120 ASSERT_TRUE(r.Changed()); |
121 EXPECT_EQ(value, r.replacement()); | 121 EXPECT_EQ(value, r.replacement()); |
122 } | 122 } |
123 | 123 |
124 TEST_F(LoadEliminationTest, LoadFieldAndLoadField) { | 124 TEST_F(LoadEliminationTest, LoadFieldAndLoadField) { |
125 Node* object = Parameter(Type::Any(), 0); | 125 Node* object = Parameter(Type::Any(), 0); |
126 Node* effect = graph()->start(); | 126 Node* effect = graph()->start(); |
127 Node* control = graph()->start(); | 127 Node* control = graph()->start(); |
128 FieldAccess const access = {kTaggedBase, | 128 FieldAccess const access = {kTaggedBase, kPointerSize, |
129 kPointerSize, | 129 MaybeHandle<Name>(), MaybeHandle<Map>(), |
130 MaybeHandle<Name>(), | 130 Type::Any(), MachineType::AnyTagged(), |
131 Type::Any(), | |
132 MachineType::AnyTagged(), | |
133 kNoWriteBarrier}; | 131 kNoWriteBarrier}; |
134 | 132 |
135 StrictMock<MockAdvancedReducerEditor> editor; | 133 StrictMock<MockAdvancedReducerEditor> editor; |
136 LoadElimination load_elimination(&editor, jsgraph(), zone()); | 134 LoadElimination load_elimination(&editor, jsgraph(), zone()); |
137 | 135 |
138 load_elimination.Reduce(graph()->start()); | 136 load_elimination.Reduce(graph()->start()); |
139 | 137 |
140 Node* load1 = effect = graph()->NewNode(simplified()->LoadField(access), | 138 Node* load1 = effect = graph()->NewNode(simplified()->LoadField(access), |
141 object, effect, control); | 139 object, effect, control); |
142 load_elimination.Reduce(load1); | 140 load_elimination.Reduce(load1); |
143 | 141 |
144 Node* load2 = effect = graph()->NewNode(simplified()->LoadField(access), | 142 Node* load2 = effect = graph()->NewNode(simplified()->LoadField(access), |
145 object, effect, control); | 143 object, effect, control); |
146 EXPECT_CALL(editor, ReplaceWithValue(load2, load1, load1, _)); | 144 EXPECT_CALL(editor, ReplaceWithValue(load2, load1, load1, _)); |
147 Reduction r = load_elimination.Reduce(load2); | 145 Reduction r = load_elimination.Reduce(load2); |
148 ASSERT_TRUE(r.Changed()); | 146 ASSERT_TRUE(r.Changed()); |
149 EXPECT_EQ(load1, r.replacement()); | 147 EXPECT_EQ(load1, r.replacement()); |
150 } | 148 } |
151 | 149 |
152 TEST_F(LoadEliminationTest, StoreFieldAndLoadField) { | 150 TEST_F(LoadEliminationTest, StoreFieldAndLoadField) { |
153 Node* object = Parameter(Type::Any(), 0); | 151 Node* object = Parameter(Type::Any(), 0); |
154 Node* value = Parameter(Type::Any(), 1); | 152 Node* value = Parameter(Type::Any(), 1); |
155 Node* effect = graph()->start(); | 153 Node* effect = graph()->start(); |
156 Node* control = graph()->start(); | 154 Node* control = graph()->start(); |
157 FieldAccess access = {kTaggedBase, | 155 FieldAccess access = {kTaggedBase, kPointerSize, |
158 kPointerSize, | 156 MaybeHandle<Name>(), MaybeHandle<Map>(), |
159 MaybeHandle<Name>(), | 157 Type::Any(), MachineType::AnyTagged(), |
160 Type::Any(), | |
161 MachineType::AnyTagged(), | |
162 kNoWriteBarrier}; | 158 kNoWriteBarrier}; |
163 | 159 |
164 StrictMock<MockAdvancedReducerEditor> editor; | 160 StrictMock<MockAdvancedReducerEditor> editor; |
165 LoadElimination load_elimination(&editor, jsgraph(), zone()); | 161 LoadElimination load_elimination(&editor, jsgraph(), zone()); |
166 | 162 |
167 load_elimination.Reduce(graph()->start()); | 163 load_elimination.Reduce(graph()->start()); |
168 | 164 |
169 Node* store = effect = graph()->NewNode(simplified()->StoreField(access), | 165 Node* store = effect = graph()->NewNode(simplified()->StoreField(access), |
170 object, value, effect, control); | 166 object, value, effect, control); |
171 load_elimination.Reduce(store); | 167 load_elimination.Reduce(store); |
172 | 168 |
173 Node* load = effect = graph()->NewNode(simplified()->LoadField(access), | 169 Node* load = effect = graph()->NewNode(simplified()->LoadField(access), |
174 object, effect, control); | 170 object, effect, control); |
175 EXPECT_CALL(editor, ReplaceWithValue(load, value, store, _)); | 171 EXPECT_CALL(editor, ReplaceWithValue(load, value, store, _)); |
176 Reduction r = load_elimination.Reduce(load); | 172 Reduction r = load_elimination.Reduce(load); |
177 ASSERT_TRUE(r.Changed()); | 173 ASSERT_TRUE(r.Changed()); |
178 EXPECT_EQ(value, r.replacement()); | 174 EXPECT_EQ(value, r.replacement()); |
179 } | 175 } |
180 | 176 |
181 TEST_F(LoadEliminationTest, StoreFieldAndStoreElementAndLoadField) { | 177 TEST_F(LoadEliminationTest, StoreFieldAndStoreElementAndLoadField) { |
182 Node* object = Parameter(Type::Any(), 0); | 178 Node* object = Parameter(Type::Any(), 0); |
183 Node* value = Parameter(Type::Any(), 1); | 179 Node* value = Parameter(Type::Any(), 1); |
184 Node* index = Parameter(Type::UnsignedSmall(), 2); | 180 Node* index = Parameter(Type::UnsignedSmall(), 2); |
185 Node* effect = graph()->start(); | 181 Node* effect = graph()->start(); |
186 Node* control = graph()->start(); | 182 Node* control = graph()->start(); |
187 FieldAccess access = {kTaggedBase, | 183 FieldAccess access = {kTaggedBase, kPointerSize, |
188 kPointerSize, | 184 MaybeHandle<Name>(), MaybeHandle<Map>(), |
189 MaybeHandle<Name>(), | 185 Type::Any(), MachineType::AnyTagged(), |
190 Type::Any(), | |
191 MachineType::AnyTagged(), | |
192 kNoWriteBarrier}; | 186 kNoWriteBarrier}; |
193 | 187 |
194 StrictMock<MockAdvancedReducerEditor> editor; | 188 StrictMock<MockAdvancedReducerEditor> editor; |
195 LoadElimination load_elimination(&editor, jsgraph(), zone()); | 189 LoadElimination load_elimination(&editor, jsgraph(), zone()); |
196 | 190 |
197 load_elimination.Reduce(graph()->start()); | 191 load_elimination.Reduce(graph()->start()); |
198 | 192 |
199 Node* store1 = effect = graph()->NewNode(simplified()->StoreField(access), | 193 Node* store1 = effect = graph()->NewNode(simplified()->StoreField(access), |
200 object, value, effect, control); | 194 object, value, effect, control); |
201 load_elimination.Reduce(store1); | 195 load_elimination.Reduce(store1); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 Reduction r = load_elimination.Reduce(load); | 275 Reduction r = load_elimination.Reduce(load); |
282 ASSERT_TRUE(r.Changed()); | 276 ASSERT_TRUE(r.Changed()); |
283 EXPECT_EQ(load, r.replacement()); | 277 EXPECT_EQ(load, r.replacement()); |
284 } | 278 } |
285 | 279 |
286 TEST_F(LoadEliminationTest, LoadFieldOnFalseBranchOfDiamond) { | 280 TEST_F(LoadEliminationTest, LoadFieldOnFalseBranchOfDiamond) { |
287 Node* object = Parameter(Type::Any(), 0); | 281 Node* object = Parameter(Type::Any(), 0); |
288 Node* check = Parameter(Type::Boolean(), 1); | 282 Node* check = Parameter(Type::Boolean(), 1); |
289 Node* effect = graph()->start(); | 283 Node* effect = graph()->start(); |
290 Node* control = graph()->start(); | 284 Node* control = graph()->start(); |
291 FieldAccess const access = {kTaggedBase, | 285 FieldAccess const access = {kTaggedBase, kPointerSize, |
292 kPointerSize, | 286 MaybeHandle<Name>(), MaybeHandle<Map>(), |
293 MaybeHandle<Name>(), | 287 Type::Any(), MachineType::AnyTagged(), |
294 Type::Any(), | |
295 MachineType::AnyTagged(), | |
296 kNoWriteBarrier}; | 288 kNoWriteBarrier}; |
297 | 289 |
298 StrictMock<MockAdvancedReducerEditor> editor; | 290 StrictMock<MockAdvancedReducerEditor> editor; |
299 LoadElimination load_elimination(&editor, jsgraph(), zone()); | 291 LoadElimination load_elimination(&editor, jsgraph(), zone()); |
300 | 292 |
301 load_elimination.Reduce(graph()->start()); | 293 load_elimination.Reduce(graph()->start()); |
302 | 294 |
303 Node* branch = graph()->NewNode(common()->Branch(), check, control); | 295 Node* branch = graph()->NewNode(common()->Branch(), check, control); |
304 | 296 |
305 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 297 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
(...skipping 13 matching lines...) Expand all Loading... |
319 Reduction r = load_elimination.Reduce(load); | 311 Reduction r = load_elimination.Reduce(load); |
320 ASSERT_TRUE(r.Changed()); | 312 ASSERT_TRUE(r.Changed()); |
321 EXPECT_EQ(load, r.replacement()); | 313 EXPECT_EQ(load, r.replacement()); |
322 } | 314 } |
323 | 315 |
324 TEST_F(LoadEliminationTest, LoadFieldOnTrueBranchOfDiamond) { | 316 TEST_F(LoadEliminationTest, LoadFieldOnTrueBranchOfDiamond) { |
325 Node* object = Parameter(Type::Any(), 0); | 317 Node* object = Parameter(Type::Any(), 0); |
326 Node* check = Parameter(Type::Boolean(), 1); | 318 Node* check = Parameter(Type::Boolean(), 1); |
327 Node* effect = graph()->start(); | 319 Node* effect = graph()->start(); |
328 Node* control = graph()->start(); | 320 Node* control = graph()->start(); |
329 FieldAccess const access = {kTaggedBase, | 321 FieldAccess const access = {kTaggedBase, kPointerSize, |
330 kPointerSize, | 322 MaybeHandle<Name>(), MaybeHandle<Map>(), |
331 MaybeHandle<Name>(), | 323 Type::Any(), MachineType::AnyTagged(), |
332 Type::Any(), | |
333 MachineType::AnyTagged(), | |
334 kNoWriteBarrier}; | 324 kNoWriteBarrier}; |
335 | 325 |
336 StrictMock<MockAdvancedReducerEditor> editor; | 326 StrictMock<MockAdvancedReducerEditor> editor; |
337 LoadElimination load_elimination(&editor, jsgraph(), zone()); | 327 LoadElimination load_elimination(&editor, jsgraph(), zone()); |
338 | 328 |
339 load_elimination.Reduce(graph()->start()); | 329 load_elimination.Reduce(graph()->start()); |
340 | 330 |
341 Node* branch = graph()->NewNode(common()->Branch(), check, control); | 331 Node* branch = graph()->NewNode(common()->Branch(), check, control); |
342 | 332 |
343 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 333 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
(...skipping 13 matching lines...) Expand all Loading... |
357 Reduction r = load_elimination.Reduce(load); | 347 Reduction r = load_elimination.Reduce(load); |
358 ASSERT_TRUE(r.Changed()); | 348 ASSERT_TRUE(r.Changed()); |
359 EXPECT_EQ(load, r.replacement()); | 349 EXPECT_EQ(load, r.replacement()); |
360 } | 350 } |
361 | 351 |
362 TEST_F(LoadEliminationTest, LoadFieldWithTypeMismatch) { | 352 TEST_F(LoadEliminationTest, LoadFieldWithTypeMismatch) { |
363 Node* object = Parameter(Type::Any(), 0); | 353 Node* object = Parameter(Type::Any(), 0); |
364 Node* value = Parameter(Type::Signed32(), 1); | 354 Node* value = Parameter(Type::Signed32(), 1); |
365 Node* effect = graph()->start(); | 355 Node* effect = graph()->start(); |
366 Node* control = graph()->start(); | 356 Node* control = graph()->start(); |
367 FieldAccess const access = {kTaggedBase, | 357 FieldAccess const access = {kTaggedBase, kPointerSize, |
368 kPointerSize, | 358 MaybeHandle<Name>(), MaybeHandle<Map>(), |
369 MaybeHandle<Name>(), | 359 Type::Unsigned31(), MachineType::AnyTagged(), |
370 Type::Unsigned31(), | |
371 MachineType::AnyTagged(), | |
372 kNoWriteBarrier}; | 360 kNoWriteBarrier}; |
373 | 361 |
374 StrictMock<MockAdvancedReducerEditor> editor; | 362 StrictMock<MockAdvancedReducerEditor> editor; |
375 LoadElimination load_elimination(&editor, jsgraph(), zone()); | 363 LoadElimination load_elimination(&editor, jsgraph(), zone()); |
376 | 364 |
377 load_elimination.Reduce(graph()->start()); | 365 load_elimination.Reduce(graph()->start()); |
378 | 366 |
379 Node* store = effect = graph()->NewNode(simplified()->StoreField(access), | 367 Node* store = effect = graph()->NewNode(simplified()->StoreField(access), |
380 object, value, effect, control); | 368 object, value, effect, control); |
381 load_elimination.Reduce(effect); | 369 load_elimination.Reduce(effect); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 Reduction r = load_elimination.Reduce(load); | 403 Reduction r = load_elimination.Reduce(load); |
416 ASSERT_TRUE(r.Changed()); | 404 ASSERT_TRUE(r.Changed()); |
417 EXPECT_THAT(r.replacement(), IsTypeGuard(value, control)); | 405 EXPECT_THAT(r.replacement(), IsTypeGuard(value, control)); |
418 } | 406 } |
419 | 407 |
420 TEST_F(LoadEliminationTest, AliasAnalysisForFinishRegion) { | 408 TEST_F(LoadEliminationTest, AliasAnalysisForFinishRegion) { |
421 Node* value0 = Parameter(Type::Signed32(), 0); | 409 Node* value0 = Parameter(Type::Signed32(), 0); |
422 Node* value1 = Parameter(Type::Signed32(), 1); | 410 Node* value1 = Parameter(Type::Signed32(), 1); |
423 Node* effect = graph()->start(); | 411 Node* effect = graph()->start(); |
424 Node* control = graph()->start(); | 412 Node* control = graph()->start(); |
425 FieldAccess const access = {kTaggedBase, | 413 FieldAccess const access = {kTaggedBase, kPointerSize, |
426 kPointerSize, | 414 MaybeHandle<Name>(), MaybeHandle<Map>(), |
427 MaybeHandle<Name>(), | 415 Type::Signed32(), MachineType::AnyTagged(), |
428 Type::Signed32(), | |
429 MachineType::AnyTagged(), | |
430 kNoWriteBarrier}; | 416 kNoWriteBarrier}; |
431 | 417 |
432 StrictMock<MockAdvancedReducerEditor> editor; | 418 StrictMock<MockAdvancedReducerEditor> editor; |
433 LoadElimination load_elimination(&editor, jsgraph(), zone()); | 419 LoadElimination load_elimination(&editor, jsgraph(), zone()); |
434 | 420 |
435 load_elimination.Reduce(effect); | 421 load_elimination.Reduce(effect); |
436 | 422 |
437 effect = graph()->NewNode( | 423 effect = graph()->NewNode( |
438 common()->BeginRegion(RegionObservability::kNotObservable), effect); | 424 common()->BeginRegion(RegionObservability::kNotObservable), effect); |
439 load_elimination.Reduce(effect); | 425 load_elimination.Reduce(effect); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 effect, control); | 458 effect, control); |
473 EXPECT_CALL(editor, ReplaceWithValue(load, value0, effect, _)); | 459 EXPECT_CALL(editor, ReplaceWithValue(load, value0, effect, _)); |
474 Reduction r = load_elimination.Reduce(load); | 460 Reduction r = load_elimination.Reduce(load); |
475 ASSERT_TRUE(r.Changed()); | 461 ASSERT_TRUE(r.Changed()); |
476 EXPECT_EQ(value0, r.replacement()); | 462 EXPECT_EQ(value0, r.replacement()); |
477 } | 463 } |
478 | 464 |
479 } // namespace compiler | 465 } // namespace compiler |
480 } // namespace internal | 466 } // namespace internal |
481 } // namespace v8 | 467 } // namespace v8 |
OLD | NEW |