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

Side by Side Diff: src/compiler/escape-analysis.cc

Issue 2680973013: [turbofan] extend escape analysis to reduce CheckMaps (Closed)
Patch Set: make MSVC happy Created 3 years, 10 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
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/escape-analysis.h" 5 #include "src/compiler/escape-analysis.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "src/base/flags.h" 9 #include "src/base/flags.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 case IrOpcode::kStoreElement: 680 case IrOpcode::kStoreElement:
681 ProcessStoreElement(node); 681 ProcessStoreElement(node);
682 break; 682 break;
683 case IrOpcode::kLoadField: 683 case IrOpcode::kLoadField:
684 case IrOpcode::kLoadElement: { 684 case IrOpcode::kLoadElement: {
685 if (Node* rep = object_analysis_->GetReplacement(node)) { 685 if (Node* rep = object_analysis_->GetReplacement(node)) {
686 if (IsAllocation(rep) && CheckUsesForEscape(node, rep)) { 686 if (IsAllocation(rep) && CheckUsesForEscape(node, rep)) {
687 RevisitInputs(rep); 687 RevisitInputs(rep);
688 RevisitUses(rep); 688 RevisitUses(rep);
689 } 689 }
690 } else {
691 Node* from = NodeProperties::GetValueInput(node, 0);
692 if (SetEscaped(from)) {
693 TRACE("Setting #%d (%s) to escaped because of unresolved load #%i\n",
694 from->id(), from->op()->mnemonic(), node->id());
695 RevisitInputs(from);
696 RevisitUses(from);
697 }
690 } 698 }
699
691 RevisitUses(node); 700 RevisitUses(node);
692 break; 701 break;
693 } 702 }
694 case IrOpcode::kPhi: 703 case IrOpcode::kPhi:
695 if (!HasEntry(node)) { 704 if (!HasEntry(node)) {
696 status_[node->id()] |= kTracked; 705 status_[node->id()] |= kTracked;
697 RevisitUses(node); 706 RevisitUses(node);
698 } 707 }
699 if (!IsAllocationPhi(node) && SetEscaped(node)) { 708 if (!IsAllocationPhi(node) && SetEscaped(node)) {
700 RevisitInputs(node); 709 RevisitInputs(node);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 } 793 }
785 // Fallthrough. 794 // Fallthrough.
786 case IrOpcode::kStoreField: 795 case IrOpcode::kStoreField:
787 case IrOpcode::kLoadField: 796 case IrOpcode::kLoadField:
788 case IrOpcode::kStoreElement: 797 case IrOpcode::kStoreElement:
789 case IrOpcode::kLoadElement: 798 case IrOpcode::kLoadElement:
790 case IrOpcode::kFrameState: 799 case IrOpcode::kFrameState:
791 case IrOpcode::kStateValues: 800 case IrOpcode::kStateValues:
792 case IrOpcode::kReferenceEqual: 801 case IrOpcode::kReferenceEqual:
793 case IrOpcode::kFinishRegion: 802 case IrOpcode::kFinishRegion:
803 case IrOpcode::kCheckMaps:
794 if (IsEscaped(use) && SetEscaped(rep)) { 804 if (IsEscaped(use) && SetEscaped(rep)) {
795 TRACE( 805 TRACE(
796 "Setting #%d (%s) to escaped because of use by escaping node " 806 "Setting #%d (%s) to escaped because of use by escaping node "
797 "#%d (%s)\n", 807 "#%d (%s)\n",
798 rep->id(), rep->op()->mnemonic(), use->id(), 808 rep->id(), rep->op()->mnemonic(), use->id(),
799 use->op()->mnemonic()); 809 use->op()->mnemonic());
800 return true; 810 return true;
801 } 811 }
802 break; 812 break;
803 case IrOpcode::kObjectIsSmi: 813 case IrOpcode::kObjectIsSmi:
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
884 replacements_(zone), 894 replacements_(zone),
885 cycle_detection_(zone), 895 cycle_detection_(zone),
886 cache_(nullptr) { 896 cache_(nullptr) {
887 // Type slot_not_analyzed_ manually. 897 // Type slot_not_analyzed_ manually.
888 double v = OpParameter<double>(slot_not_analyzed_); 898 double v = OpParameter<double>(slot_not_analyzed_);
889 NodeProperties::SetType(slot_not_analyzed_, Type::Range(v, v, zone)); 899 NodeProperties::SetType(slot_not_analyzed_, Type::Range(v, v, zone));
890 } 900 }
891 901
892 EscapeAnalysis::~EscapeAnalysis() {} 902 EscapeAnalysis::~EscapeAnalysis() {}
893 903
894 void EscapeAnalysis::Run() { 904 bool EscapeAnalysis::Run() {
895 replacements_.resize(graph()->NodeCount()); 905 replacements_.resize(graph()->NodeCount());
896 status_analysis_->AssignAliases(); 906 status_analysis_->AssignAliases();
897 if (status_analysis_->AliasCount() > 0) { 907 if (status_analysis_->AliasCount() > 0) {
898 cache_ = new (zone()) MergeCache(zone()); 908 cache_ = new (zone()) MergeCache(zone());
899 replacements_.resize(graph()->NodeCount()); 909 replacements_.resize(graph()->NodeCount());
900 status_analysis_->ResizeStatusVector(); 910 status_analysis_->ResizeStatusVector();
901 RunObjectAnalysis(); 911 RunObjectAnalysis();
902 status_analysis_->RunStatusAnalysis(); 912 status_analysis_->RunStatusAnalysis();
913 return true;
914 } else {
915 return false;
903 } 916 }
904 } 917 }
905 918
906 void EscapeStatusAnalysis::AssignAliases() { 919 void EscapeStatusAnalysis::AssignAliases() {
907 size_t max_size = 1024; 920 size_t max_size = 1024;
908 size_t min_size = 32; 921 size_t min_size = 32;
909 size_t stack_size = 922 size_t stack_size =
910 std::min(std::max(graph()->NodeCount() / 5, min_size), max_size); 923 std::min(std::max(graph()->NodeCount() / 5, min_size), max_size);
911 stack_.reserve(stack_size); 924 stack_.reserve(stack_size);
912 ResizeStatusVector(); 925 ResizeStatusVector();
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
1098 break; 1111 break;
1099 case IrOpcode::kLoadField: 1112 case IrOpcode::kLoadField:
1100 ProcessLoadField(node); 1113 ProcessLoadField(node);
1101 break; 1114 break;
1102 case IrOpcode::kStoreElement: 1115 case IrOpcode::kStoreElement:
1103 ProcessStoreElement(node); 1116 ProcessStoreElement(node);
1104 break; 1117 break;
1105 case IrOpcode::kLoadElement: 1118 case IrOpcode::kLoadElement:
1106 ProcessLoadElement(node); 1119 ProcessLoadElement(node);
1107 break; 1120 break;
1121 case IrOpcode::kCheckMaps:
1122 ProcessCheckMaps(node);
1123 break;
1108 case IrOpcode::kStart: 1124 case IrOpcode::kStart:
1109 ProcessStart(node); 1125 ProcessStart(node);
1110 break; 1126 break;
1111 case IrOpcode::kEffectPhi: 1127 case IrOpcode::kEffectPhi:
1112 return ProcessEffectPhi(node); 1128 return ProcessEffectPhi(node);
1113 break; 1129 break;
1114 default: 1130 default:
1115 if (node->op()->EffectInputCount() > 0) { 1131 if (node->op()->EffectInputCount() > 0) {
1116 ForwardVirtualState(node); 1132 ForwardVirtualState(node);
1117 } 1133 }
(...skipping 17 matching lines...) Expand all
1135 case IrOpcode::kStoreField: 1151 case IrOpcode::kStoreField:
1136 case IrOpcode::kLoadField: 1152 case IrOpcode::kLoadField:
1137 case IrOpcode::kStoreElement: 1153 case IrOpcode::kStoreElement:
1138 case IrOpcode::kLoadElement: 1154 case IrOpcode::kLoadElement:
1139 case IrOpcode::kFrameState: 1155 case IrOpcode::kFrameState:
1140 case IrOpcode::kStateValues: 1156 case IrOpcode::kStateValues:
1141 case IrOpcode::kReferenceEqual: 1157 case IrOpcode::kReferenceEqual:
1142 case IrOpcode::kFinishRegion: 1158 case IrOpcode::kFinishRegion:
1143 case IrOpcode::kObjectIsSmi: 1159 case IrOpcode::kObjectIsSmi:
1144 break; 1160 break;
1161 case IrOpcode::kCheckMaps: {
1162 CheckMapsParameters params = CheckMapsParametersOf(node->op());
1163 if (params.flags() == CheckMapsFlag::kNone) break;
1164 } // Fallthrough.
1145 default: 1165 default:
1146 VirtualState* state = virtual_states_[node->id()]; 1166 VirtualState* state = virtual_states_[node->id()];
1147 if (VirtualObject* obj = 1167 if (VirtualObject* obj =
1148 GetVirtualObject(state, ResolveReplacement(input))) { 1168 GetVirtualObject(state, ResolveReplacement(input))) {
1149 if (!obj->AllFieldsClear()) { 1169 if (!obj->AllFieldsClear()) {
1150 obj = CopyForModificationAt(obj, state, node); 1170 obj = CopyForModificationAt(obj, state, node);
1151 obj->ClearAllFields(); 1171 obj->ClearAllFields();
1152 TRACE("Cleared all fields of @%d:#%d\n", 1172 TRACE("Cleared all fields of @%d:#%d\n",
1153 status_analysis_->GetAlias(obj->id()), obj->id()); 1173 status_analysis_->GetAlias(obj->id()), obj->id());
1154 } 1174 }
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
1488 } else if (from->opcode() == IrOpcode::kPhi && 1508 } else if (from->opcode() == IrOpcode::kPhi &&
1489 IsOffsetForFieldAccessCorrect(FieldAccessOf(node->op()))) { 1509 IsOffsetForFieldAccessCorrect(FieldAccessOf(node->op()))) {
1490 int offset = OffsetForFieldAccess(node); 1510 int offset = OffsetForFieldAccess(node);
1491 // Only binary phis are supported for now. 1511 // Only binary phis are supported for now.
1492 ProcessLoadFromPhi(offset, from, node, state); 1512 ProcessLoadFromPhi(offset, from, node, state);
1493 } else { 1513 } else {
1494 UpdateReplacement(state, node, nullptr); 1514 UpdateReplacement(state, node, nullptr);
1495 } 1515 }
1496 } 1516 }
1497 1517
1518 void EscapeAnalysis::ProcessCheckMaps(Node* node) {
1519 DCHECK_EQ(node->opcode(), IrOpcode::kCheckMaps);
1520 ForwardVirtualState(node);
1521 Node* checked = ResolveReplacement(NodeProperties::GetValueInput(node, 0));
1522 VirtualState* state = virtual_states_[node->id()];
1523 if (VirtualObject* object = GetVirtualObject(state, checked)) {
1524 if (!object->IsTracked()) {
1525 if (status_analysis_->SetEscaped(node)) {
1526 TRACE(
1527 "Setting #%d (%s) to escaped because checked object #%i is not "
1528 "tracked\n",
1529 node->id(), node->op()->mnemonic(), object->id());
1530 }
1531 return;
1532 }
1533 CheckMapsParameters params = CheckMapsParametersOf(node->op());
1534
1535 Node* value = object->GetField(HeapObject::kMapOffset / kPointerSize);
1536 if (value) {
1537 value = ResolveReplacement(value);
1538 if (value->opcode() == IrOpcode::kHeapConstant &&
1539 params.maps().contains(ZoneHandleSet<Map>(
1540 Handle<Map>::cast(OpParameter<Handle<HeapObject>>(value))))) {
1541 return;
Benedikt Meurer 2017/02/13 15:02:01 Please add a TRACE message here. And a to-do that
1542 }
1543 }
1544 }
1545 if (status_analysis_->SetEscaped(node)) {
1546 TRACE("Setting #%d (%s) to escaped (checking #%i)\n", node->id(),
1547 node->op()->mnemonic(), checked->id());
1548 }
1549 }
1550
1498 void EscapeAnalysis::ProcessLoadElement(Node* node) { 1551 void EscapeAnalysis::ProcessLoadElement(Node* node) {
1499 DCHECK_EQ(node->opcode(), IrOpcode::kLoadElement); 1552 DCHECK_EQ(node->opcode(), IrOpcode::kLoadElement);
1500 ForwardVirtualState(node); 1553 ForwardVirtualState(node);
1501 Node* from = ResolveReplacement(NodeProperties::GetValueInput(node, 0)); 1554 Node* from = ResolveReplacement(NodeProperties::GetValueInput(node, 0));
1502 VirtualState* state = virtual_states_[node->id()]; 1555 VirtualState* state = virtual_states_[node->id()];
1503 Node* index_node = node->InputAt(1); 1556 Node* index_node = node->InputAt(1);
1504 NumberMatcher index(index_node); 1557 NumberMatcher index(index_node);
1505 DCHECK(index_node->opcode() != IrOpcode::kInt32Constant && 1558 DCHECK(index_node->opcode() != IrOpcode::kInt32Constant &&
1506 index_node->opcode() != IrOpcode::kInt64Constant && 1559 index_node->opcode() != IrOpcode::kInt64Constant &&
1507 index_node->opcode() != IrOpcode::kFloat32Constant && 1560 index_node->opcode() != IrOpcode::kFloat32Constant &&
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
1729 } 1782 }
1730 } 1783 }
1731 return false; 1784 return false;
1732 } 1785 }
1733 1786
1734 Graph* EscapeAnalysis::graph() const { return status_analysis_->graph(); } 1787 Graph* EscapeAnalysis::graph() const { return status_analysis_->graph(); }
1735 1788
1736 } // namespace compiler 1789 } // namespace compiler
1737 } // namespace internal 1790 } // namespace internal
1738 } // namespace v8 1791 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698