| 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 |