Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: src/compiler/load-elimination.cc

Issue 2218703003: [turbofan] Add support for copy-on-write element stores. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix off-by-one loop iteration count. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/load-elimination.h ('k') | src/compiler/opcodes.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 6
7 #include "src/compiler/js-graph.h"
7 #include "src/compiler/node-properties.h" 8 #include "src/compiler/node-properties.h"
8 #include "src/compiler/simplified-operator.h" 9 #include "src/compiler/simplified-operator.h"
9 10
10 namespace v8 { 11 namespace v8 {
11 namespace internal { 12 namespace internal {
12 namespace compiler { 13 namespace compiler {
13 14
14 namespace { 15 namespace {
15 16
16 enum Aliasing { kNoAlias, kMayAlias, kMustAlias }; 17 enum Aliasing { kNoAlias, kMayAlias, kMustAlias };
(...skipping 29 matching lines...) Expand all
46 bool MayAlias(Node* a, Node* b) { return QueryAlias(a, b) != kNoAlias; } 47 bool MayAlias(Node* a, Node* b) { return QueryAlias(a, b) != kNoAlias; }
47 48
48 bool MustAlias(Node* a, Node* b) { return QueryAlias(a, b) == kMustAlias; } 49 bool MustAlias(Node* a, Node* b) { return QueryAlias(a, b) == kMustAlias; }
49 50
50 } // namespace 51 } // namespace
51 52
52 Reduction LoadElimination::Reduce(Node* node) { 53 Reduction LoadElimination::Reduce(Node* node) {
53 switch (node->opcode()) { 54 switch (node->opcode()) {
54 case IrOpcode::kCheckMaps: 55 case IrOpcode::kCheckMaps:
55 return ReduceCheckMaps(node); 56 return ReduceCheckMaps(node);
57 case IrOpcode::kEnsureWritableFastElements:
58 return ReduceEnsureWritableFastElements(node);
56 case IrOpcode::kTransitionElementsKind: 59 case IrOpcode::kTransitionElementsKind:
57 return ReduceTransitionElementsKind(node); 60 return ReduceTransitionElementsKind(node);
58 case IrOpcode::kLoadField: 61 case IrOpcode::kLoadField:
59 return ReduceLoadField(node); 62 return ReduceLoadField(node);
60 case IrOpcode::kStoreField: 63 case IrOpcode::kStoreField:
61 return ReduceStoreField(node); 64 return ReduceStoreField(node);
62 case IrOpcode::kLoadElement: 65 case IrOpcode::kLoadElement:
63 return ReduceLoadElement(node); 66 return ReduceLoadElement(node);
64 case IrOpcode::kStoreElement: 67 case IrOpcode::kStoreElement:
65 return ReduceStoreElement(node); 68 return ReduceStoreElement(node);
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 if (map == object_map) return Replace(effect); 322 if (map == object_map) return Replace(effect);
320 } 323 }
321 } 324 }
322 if (map_input_count == 1) { 325 if (map_input_count == 1) {
323 Node* const map0 = NodeProperties::GetValueInput(node, 1); 326 Node* const map0 = NodeProperties::GetValueInput(node, 1);
324 state = state->AddField(object, 0, map0, zone()); 327 state = state->AddField(object, 0, map0, zone());
325 } 328 }
326 return UpdateState(node, state); 329 return UpdateState(node, state);
327 } 330 }
328 331
332 Reduction LoadElimination::ReduceEnsureWritableFastElements(Node* node) {
333 Node* const object = NodeProperties::GetValueInput(node, 0);
334 Node* const elements = NodeProperties::GetValueInput(node, 1);
335 Node* const effect = NodeProperties::GetEffectInput(node);
336 AbstractState const* state = node_states_.Get(effect);
337 if (state == nullptr) return NoChange();
338 Node* fixed_array_map = jsgraph()->FixedArrayMapConstant();
339 if (Node* const elements_map = state->LookupField(elements, 0)) {
340 // Check if the {elements} already have the fixed array map.
341 if (elements_map == fixed_array_map) {
342 ReplaceWithValue(node, elements, effect);
343 return Replace(elements);
344 }
345 }
346 // We know that the resulting elements have the fixed array map.
347 state = state->AddField(node, 0, fixed_array_map, zone());
348 // Kill the previous elements on {object}.
349 state = state->KillField(object, 2, zone());
350 // Add the new elements on {object}.
351 state = state->AddField(object, 2, node, zone());
352 return UpdateState(node, state);
353 }
354
329 Reduction LoadElimination::ReduceTransitionElementsKind(Node* node) { 355 Reduction LoadElimination::ReduceTransitionElementsKind(Node* node) {
330 Node* const object = NodeProperties::GetValueInput(node, 0); 356 Node* const object = NodeProperties::GetValueInput(node, 0);
331 Node* const source_map = NodeProperties::GetValueInput(node, 1); 357 Node* const source_map = NodeProperties::GetValueInput(node, 1);
332 Node* const target_map = NodeProperties::GetValueInput(node, 2); 358 Node* const target_map = NodeProperties::GetValueInput(node, 2);
333 Node* const effect = NodeProperties::GetEffectInput(node); 359 Node* const effect = NodeProperties::GetEffectInput(node);
334 AbstractState const* state = node_states_.Get(effect); 360 AbstractState const* state = node_states_.Get(effect);
335 if (state == nullptr) return NoChange(); 361 if (state == nullptr) return NoChange();
336 if (Node* const object_map = state->LookupField(object, 0)) { 362 if (Node* const object_map = state->LookupField(object, 0)) {
337 state = state->KillField(object, 0, zone()); 363 state = state->KillField(object, 0, zone());
338 if (source_map == object_map) { 364 if (source_map == object_map) {
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 for (int i = 1; i < control->InputCount(); ++i) { 571 for (int i = 1; i < control->InputCount(); ++i) {
546 queue.push(node->InputAt(i)); 572 queue.push(node->InputAt(i));
547 } 573 }
548 while (!queue.empty()) { 574 while (!queue.empty()) {
549 Node* const current = queue.front(); 575 Node* const current = queue.front();
550 queue.pop(); 576 queue.pop();
551 if (visited.find(current) == visited.end()) { 577 if (visited.find(current) == visited.end()) {
552 visited.insert(current); 578 visited.insert(current);
553 if (!current->op()->HasProperty(Operator::kNoWrite)) { 579 if (!current->op()->HasProperty(Operator::kNoWrite)) {
554 switch (current->opcode()) { 580 switch (current->opcode()) {
581 case IrOpcode::kEnsureWritableFastElements: {
582 Node* const object = NodeProperties::GetValueInput(current, 0);
583 Node* const elements = NodeProperties::GetValueInput(current, 1);
584 state = state->KillField(elements, 0, zone());
585 state = state->KillField(object, 2, zone());
586 break;
587 }
588 case IrOpcode::kTransitionElementsKind: {
589 Node* const object = NodeProperties::GetValueInput(current, 0);
590 state = state->KillField(object, 0, zone());
591 state = state->KillField(object, 2, zone());
592 break;
593 }
555 case IrOpcode::kStoreField: { 594 case IrOpcode::kStoreField: {
556 FieldAccess const& access = FieldAccessOf(current->op()); 595 FieldAccess const& access = FieldAccessOf(current->op());
557 Node* const object = NodeProperties::GetValueInput(current, 0); 596 Node* const object = NodeProperties::GetValueInput(current, 0);
558 int field_index = FieldIndexOf(access); 597 int field_index = FieldIndexOf(access);
559 if (field_index < 0) return empty_state(); 598 if (field_index < 0) return empty_state();
560 state = state->KillField(object, field_index, zone()); 599 state = state->KillField(object, field_index, zone());
561 break; 600 break;
562 } 601 }
563 case IrOpcode::kStoreElement: { 602 case IrOpcode::kStoreElement: {
564 Node* const object = NodeProperties::GetValueInput(current, 0); 603 Node* const object = NodeProperties::GetValueInput(current, 0);
565 Node* const index = NodeProperties::GetValueInput(current, 1); 604 Node* const index = NodeProperties::GetValueInput(current, 1);
566 state = state->KillElement(object, index, zone()); 605 state = state->KillElement(object, index, zone());
567 break; 606 break;
568 } 607 }
608 case IrOpcode::kStoreBuffer:
609 case IrOpcode::kStoreTypedElement: {
610 // Doesn't affect anything we track with the state currently.
611 break;
612 }
569 default: 613 default:
570 return empty_state(); 614 return empty_state();
571 } 615 }
572 } 616 }
573 for (int i = 0; i < current->op()->EffectInputCount(); ++i) { 617 for (int i = 0; i < current->op()->EffectInputCount(); ++i) {
574 queue.push(NodeProperties::GetEffectInput(current, i)); 618 queue.push(NodeProperties::GetEffectInput(current, i));
575 } 619 }
576 } 620 }
577 } 621 }
578 return state; 622 return state;
(...skipping 27 matching lines...) Expand all
606 DCHECK_EQ(kTaggedBase, access.base_is_tagged); 650 DCHECK_EQ(kTaggedBase, access.base_is_tagged);
607 DCHECK_EQ(0, access.offset % kPointerSize); 651 DCHECK_EQ(0, access.offset % kPointerSize);
608 int field_index = access.offset / kPointerSize; 652 int field_index = access.offset / kPointerSize;
609 if (field_index >= static_cast<int>(kMaxTrackedFields)) return -1; 653 if (field_index >= static_cast<int>(kMaxTrackedFields)) return -1;
610 return field_index; 654 return field_index;
611 } 655 }
612 656
613 } // namespace compiler 657 } // namespace compiler
614 } // namespace internal 658 } // namespace internal
615 } // namespace v8 659 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/load-elimination.h ('k') | src/compiler/opcodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698