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

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

Issue 1654163003: [turbofan] Delay initialization in escape analysis (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Make --trace-turbo-escape a proper debug flag Created 4 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
« no previous file with comments | « src/compiler/escape-analysis.h ('k') | src/compiler/escape-analysis-reducer.cc » ('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 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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 } 109 }
110 bool AllFieldsClear() { 110 bool AllFieldsClear() {
111 for (size_t i = 0; i < fields_.size(); ++i) { 111 for (size_t i = 0; i < fields_.size(); ++i) {
112 if (fields_[i] != nullptr) { 112 if (fields_[i] != nullptr) {
113 return false; 113 return false;
114 } 114 }
115 } 115 }
116 return true; 116 return true;
117 } 117 }
118 bool UpdateFrom(const VirtualObject& other); 118 bool UpdateFrom(const VirtualObject& other);
119 bool MergeFrom(MergeCache* cache, Node* at, Graph* graph,
120 CommonOperatorBuilder* common);
119 void SetObjectState(Node* node) { object_state_ = node; } 121 void SetObjectState(Node* node) { object_state_ = node; }
120 Node* GetObjectState() const { return object_state_; } 122 Node* GetObjectState() const { return object_state_; }
121 bool IsCopyRequired() const { return status_ & kCopyRequired; } 123 bool IsCopyRequired() const { return status_ & kCopyRequired; }
122 void SetCopyRequired() { status_ |= kCopyRequired; } 124 void SetCopyRequired() { status_ |= kCopyRequired; }
123 bool NeedCopyForModification() { 125 bool NeedCopyForModification() {
124 if (!IsCopyRequired() || !IsInitialized()) { 126 if (!IsCopyRequired() || !IsInitialized()) {
125 return false; 127 return false;
126 } 128 }
127 return true; 129 return true;
128 } 130 }
129 131
130 NodeId id() const { return id_; } 132 NodeId id() const { return id_; }
131 void id(NodeId id) { id_ = id; } 133 void id(NodeId id) { id_ = id; }
132 134
133 private: 135 private:
136 bool MergeFields(size_t i, Node* at, MergeCache* cache, Graph* graph,
137 CommonOperatorBuilder* common);
138
134 NodeId id_; 139 NodeId id_;
135 StatusFlags status_; 140 StatusFlags status_;
136 ZoneVector<Node*> fields_; 141 ZoneVector<Node*> fields_;
137 ZoneVector<bool> phi_; 142 ZoneVector<bool> phi_;
138 Node* object_state_; 143 Node* object_state_;
139 VirtualState* owner_; 144 VirtualState* owner_;
140 145
141 DISALLOW_COPY_AND_ASSIGN(VirtualObject); 146 DISALLOW_COPY_AND_ASSIGN(VirtualObject);
142 }; 147 };
143 148
(...skipping 25 matching lines...) Expand all
169 : info_(state.info_.size(), nullptr, state.info_.get_allocator().zone()), 174 : info_(state.info_.size(), nullptr, state.info_.get_allocator().zone()),
170 owner_(owner) { 175 owner_(owner) {
171 for (size_t i = 0; i < info_.size(); ++i) { 176 for (size_t i = 0; i < info_.size(); ++i) {
172 if (state.info_[i]) { 177 if (state.info_[i]) {
173 info_[i] = state.info_[i]; 178 info_[i] = state.info_[i];
174 } 179 }
175 } 180 }
176 } 181 }
177 182
178 VirtualObject* VirtualObjectFromAlias(size_t alias); 183 VirtualObject* VirtualObjectFromAlias(size_t alias);
179 VirtualObject* GetOrCreateTrackedVirtualObject(Alias alias, NodeId id,
180 size_t fields,
181 bool initialized, Zone* zone,
182 bool force_copy);
183 void SetVirtualObject(Alias alias, VirtualObject* state); 184 void SetVirtualObject(Alias alias, VirtualObject* state);
184 bool UpdateFrom(VirtualState* state, Zone* zone); 185 bool UpdateFrom(VirtualState* state, Zone* zone);
185 bool MergeFrom(MergeCache* cache, Zone* zone, Graph* graph, 186 bool MergeFrom(MergeCache* cache, Zone* zone, Graph* graph,
186 CommonOperatorBuilder* common, Node* control, int arity); 187 CommonOperatorBuilder* common, Node* at);
187 size_t size() const { return info_.size(); } 188 size_t size() const { return info_.size(); }
188 Node* owner() const { return owner_; } 189 Node* owner() const { return owner_; }
189 VirtualObject* Copy(VirtualObject* obj, Alias alias); 190 VirtualObject* Copy(VirtualObject* obj, Alias alias);
190 void SetCopyRequired() { 191 void SetCopyRequired() {
191 for (VirtualObject* obj : info_) { 192 for (VirtualObject* obj : info_) {
192 if (obj) obj->SetCopyRequired(); 193 if (obj) obj->SetCopyRequired();
193 } 194 }
194 } 195 }
195 196
196 private: 197 private:
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 static_cast<void*>(this), alias, obj->id(), static_cast<void*>(obj), 282 static_cast<void*>(this), alias, obj->id(), static_cast<void*>(obj),
282 static_cast<void*>(new_obj)); 283 static_cast<void*>(new_obj));
283 info_[alias] = new_obj; 284 info_[alias] = new_obj;
284 return new_obj; 285 return new_obj;
285 } 286 }
286 287
287 VirtualObject* VirtualState::VirtualObjectFromAlias(size_t alias) { 288 VirtualObject* VirtualState::VirtualObjectFromAlias(size_t alias) {
288 return info_[alias]; 289 return info_[alias];
289 } 290 }
290 291
291 VirtualObject* VirtualState::GetOrCreateTrackedVirtualObject(
292 Alias alias, NodeId id, size_t field_number, bool initialized, Zone* zone,
293 bool force_copy) {
294 if (!force_copy) {
295 if (VirtualObject* obj = VirtualObjectFromAlias(alias)) {
296 return obj;
297 }
298 }
299 VirtualObject* obj = new (zone) VirtualObject(id, this, zone, 0, initialized);
300 SetVirtualObject(alias, obj);
301 return obj;
302 }
303
304 void VirtualState::SetVirtualObject(Alias alias, VirtualObject* obj) { 292 void VirtualState::SetVirtualObject(Alias alias, VirtualObject* obj) {
305 info_[alias] = obj; 293 info_[alias] = obj;
306 } 294 }
307 295
308 bool VirtualState::UpdateFrom(VirtualState* from, Zone* zone) { 296 bool VirtualState::UpdateFrom(VirtualState* from, Zone* zone) {
309 if (from == this) return false; 297 if (from == this) return false;
310 bool changed = false; 298 bool changed = false;
311 for (Alias alias = 0; alias < size(); ++alias) { 299 for (Alias alias = 0; alias < size(); ++alias) {
312 VirtualObject* ls = VirtualObjectFromAlias(alias); 300 VirtualObject* ls = VirtualObjectFromAlias(alias);
313 VirtualObject* rs = from->VirtualObjectFromAlias(alias); 301 VirtualObject* rs = from->VirtualObjectFromAlias(alias);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 Node* input = NodeProperties::GetValueInput(phi, static_cast<int>(i)); 343 Node* input = NodeProperties::GetValueInput(phi, static_cast<int>(i));
356 if (!IsEquivalentPhi(input, inputs[i])) { 344 if (!IsEquivalentPhi(input, inputs[i])) {
357 return false; 345 return false;
358 } 346 }
359 } 347 }
360 return true; 348 return true;
361 } 349 }
362 350
363 } // namespace 351 } // namespace
364 352
365 Node* EscapeAnalysis::GetReplacementIfSame(ZoneVector<VirtualObject*>& objs) { 353 bool VirtualObject::MergeFields(size_t i, Node* at, MergeCache* cache,
366 Node* rep = GetReplacement(objs.front()->id()); 354 Graph* graph, CommonOperatorBuilder* common) {
367 for (VirtualObject* obj : objs) { 355 bool changed = false;
368 if (GetReplacement(obj->id()) != rep) { 356 int value_input_count = static_cast<int>(cache->fields().size());
369 return nullptr; 357 Node* rep = GetField(i);
358 if (!rep || !IsCreatedPhi(i)) {
359 Node* control = NodeProperties::GetControlInput(at);
360 cache->fields().push_back(control);
361 Node* phi = graph->NewNode(
362 common->Phi(MachineRepresentation::kTagged, value_input_count),
363 value_input_count + 1, &cache->fields().front());
364 SetField(i, phi, true);
365 #ifdef DEBUG
366 if (FLAG_trace_turbo_escape) {
367 PrintF(" Creating Phi #%d as merge of", phi->id());
368 for (int i = 0; i < value_input_count; i++) {
369 PrintF(" #%d (%s)", cache->fields()[i]->id(),
370 cache->fields()[i]->op()->mnemonic());
371 }
372 PrintF("\n");
373 }
374 #endif
375 changed = true;
376 } else {
377 DCHECK(rep->opcode() == IrOpcode::kPhi);
378 for (int n = 0; n < value_input_count; ++n) {
379 Node* old = NodeProperties::GetValueInput(rep, n);
380 if (old != cache->fields()[n]) {
381 changed = true;
382 NodeProperties::ReplaceValueInput(rep, cache->fields()[n], n);
383 }
370 } 384 }
371 } 385 }
372 return rep; 386 return changed;
387 }
388
389 bool VirtualObject::MergeFrom(MergeCache* cache, Node* at, Graph* graph,
390 CommonOperatorBuilder* common) {
391 DCHECK(at->opcode() == IrOpcode::kEffectPhi ||
392 at->opcode() == IrOpcode::kPhi);
393 bool changed = false;
394 for (size_t i = 0; i < field_count(); ++i) {
395 if (Node* field = cache->GetFields(i)) {
396 changed = changed || GetField(i) != field;
397 SetField(i, field);
398 TRACE(" Field %zu agree on rep #%d\n", i, field->id());
399 } else {
400 int arity = at->opcode() == IrOpcode::kEffectPhi
401 ? at->op()->EffectInputCount()
402 : at->op()->ValueInputCount();
403 if (cache->fields().size() == arity) {
404 changed = MergeFields(i, at, cache, graph, common) || changed;
405 } else {
406 if (GetField(i) != nullptr) {
407 TRACE(" Field %zu cleared\n", i);
408 changed = true;
409 }
410 SetField(i, nullptr);
411 }
412 }
413 }
414 return changed;
373 } 415 }
374 416
375 bool VirtualState::MergeFrom(MergeCache* cache, Zone* zone, Graph* graph, 417 bool VirtualState::MergeFrom(MergeCache* cache, Zone* zone, Graph* graph,
376 CommonOperatorBuilder* common, Node* control, 418 CommonOperatorBuilder* common, Node* at) {
377 int arity) {
378 DCHECK_GT(cache->states().size(), 0u); 419 DCHECK_GT(cache->states().size(), 0u);
379 bool changed = false; 420 bool changed = false;
380 for (Alias alias = 0; alias < size(); ++alias) { 421 for (Alias alias = 0; alias < size(); ++alias) {
381 cache->objects().clear(); 422 cache->objects().clear();
382 VirtualObject* mergeObject = VirtualObjectFromAlias(alias); 423 VirtualObject* mergeObject = VirtualObjectFromAlias(alias);
383 bool copy_merge_object = false; 424 bool copy_merge_object = false;
384 size_t fields = std::numeric_limits<size_t>::max(); 425 size_t fields = std::numeric_limits<size_t>::max();
385 for (VirtualState* state : cache->states()) { 426 for (VirtualState* state : cache->states()) {
386 if (VirtualObject* obj = state->VirtualObjectFromAlias(alias)) { 427 if (VirtualObject* obj = state->VirtualObjectFromAlias(alias)) {
387 cache->objects().push_back(obj); 428 cache->objects().push_back(obj);
388 if (mergeObject == obj) { 429 if (mergeObject == obj) {
389 copy_merge_object = true; 430 copy_merge_object = true;
390 changed = true;
391 } 431 }
392 fields = std::min(obj->field_count(), fields); 432 fields = std::min(obj->field_count(), fields);
393 } 433 }
394 } 434 }
395 if (cache->objects().size() == cache->states().size()) { 435 if (cache->objects().size() == cache->states().size()) {
396 mergeObject = GetOrCreateTrackedVirtualObject( 436 if (!mergeObject) {
397 alias, cache->objects().front()->id(), 437 VirtualObject* obj = new (zone)
398 cache->objects().front()->IsInitialized(), fields, zone, 438 VirtualObject(cache->objects().front()->id(), this, zone, fields,
399 copy_merge_object); 439 cache->objects().front()->IsInitialized());
440 SetVirtualObject(alias, obj);
441 mergeObject = obj;
442 changed = true;
443 } else if (copy_merge_object) {
444 VirtualObject* obj = new (zone) VirtualObject(this, *mergeObject);
445 SetVirtualObject(alias, obj);
446 mergeObject = obj;
447 changed = true;
448 } else {
449 changed = mergeObject->ResizeFields(fields) || changed;
450 }
400 #ifdef DEBUG 451 #ifdef DEBUG
401 if (FLAG_trace_turbo_escape) { 452 if (FLAG_trace_turbo_escape) {
402 PrintF(" Alias @%d, merging into %p virtual objects", alias, 453 PrintF(" Alias @%d, merging into %p virtual objects", alias,
403 static_cast<void*>(mergeObject)); 454 static_cast<void*>(mergeObject));
404 for (size_t i = 0; i < cache->objects().size(); i++) { 455 for (size_t i = 0; i < cache->objects().size(); i++) {
405 PrintF(" %p", static_cast<void*>(cache->objects()[i])); 456 PrintF(" %p", static_cast<void*>(cache->objects()[i]));
406 } 457 }
407 PrintF("\n"); 458 PrintF("\n");
408 } 459 }
409 #endif // DEBUG 460 #endif // DEBUG
410 changed = mergeObject->ResizeFields(fields) || changed; 461 changed = mergeObject->MergeFrom(cache, at, graph, common) || changed;
411 for (size_t i = 0; i < fields; ++i) {
412 if (Node* field = cache->GetFields(i)) {
413 changed = changed || mergeObject->GetField(i) != field;
414 mergeObject->SetField(i, field);
415 TRACE(" Field %zu agree on rep #%d\n", i, field->id());
416 } else {
417 int value_input_count = static_cast<int>(cache->fields().size());
418 if (cache->fields().size() == arity) {
419 Node* rep = mergeObject->GetField(i);
420 if (!rep || !mergeObject->IsCreatedPhi(i)) {
421 cache->fields().push_back(control);
422 Node* phi = graph->NewNode(
423 common->Phi(MachineRepresentation::kTagged,
424 value_input_count),
425 value_input_count + 1, &cache->fields().front());
426 mergeObject->SetField(i, phi, true);
427 #ifdef DEBUG
428 if (FLAG_trace_turbo_escape) {
429 PrintF(" Creating Phi #%d as merge of", phi->id());
430 for (int i = 0; i < value_input_count; i++) {
431 PrintF(" #%d (%s)", cache->fields()[i]->id(),
432 cache->fields()[i]->op()->mnemonic());
433 }
434 PrintF("\n");
435 }
436 #endif // DEBUG
437 changed = true;
438 } else {
439 DCHECK(rep->opcode() == IrOpcode::kPhi);
440 for (int n = 0; n < value_input_count; ++n) {
441 Node* old = NodeProperties::GetValueInput(rep, n);
442 if (old != cache->fields()[n]) {
443 changed = true;
444 NodeProperties::ReplaceValueInput(rep, cache->fields()[n], n);
445 }
446 }
447 }
448 } else {
449 if (mergeObject->GetField(i) != nullptr) {
450 TRACE(" Field %zu cleared\n", i);
451 changed = true;
452 }
453 mergeObject->SetField(i, nullptr);
454 }
455 }
456 }
457 } else { 462 } else {
458 if (mergeObject) { 463 if (mergeObject) {
459 TRACE(" Alias %d, virtual object removed\n", alias); 464 TRACE(" Alias %d, virtual object removed\n", alias);
460 changed = true; 465 changed = true;
461 } 466 }
462 SetVirtualObject(alias, nullptr); 467 SetVirtualObject(alias, nullptr);
463 } 468 }
464 } 469 }
465 return changed; 470 return changed;
466 } 471 }
467 472
468 EscapeStatusAnalysis::EscapeStatusAnalysis(EscapeAnalysis* object_analysis, 473 EscapeStatusAnalysis::EscapeStatusAnalysis(EscapeAnalysis* object_analysis,
469 Graph* graph, Zone* zone) 474 Graph* graph, Zone* zone)
470 : stack_(zone), 475 : stack_(zone),
471 object_analysis_(object_analysis), 476 object_analysis_(object_analysis),
472 graph_(graph), 477 graph_(graph),
473 zone_(zone), 478 zone_(zone),
474 status_(graph->NodeCount(), kUnknown, zone), 479 status_(zone),
475 next_free_alias_(0), 480 next_free_alias_(0),
476 status_stack_(zone), 481 status_stack_(zone),
477 aliases_(zone) {} 482 aliases_(zone) {}
478 483
479 EscapeStatusAnalysis::~EscapeStatusAnalysis() {} 484 EscapeStatusAnalysis::~EscapeStatusAnalysis() {}
480 485
481 bool EscapeStatusAnalysis::HasEntry(Node* node) { 486 bool EscapeStatusAnalysis::HasEntry(Node* node) {
482 return status_[node->id()] & (kTracked | kEscaped); 487 return status_[node->id()] & (kTracked | kEscaped);
483 } 488 }
484 489
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 replacements_.resize(graph()->NodeCount()); 775 replacements_.resize(graph()->NodeCount());
771 status_analysis_.ResizeStatusVector(); 776 status_analysis_.ResizeStatusVector();
772 RunObjectAnalysis(); 777 RunObjectAnalysis();
773 status_analysis_.RunStatusAnalysis(); 778 status_analysis_.RunStatusAnalysis();
774 } 779 }
775 } 780 }
776 781
777 void EscapeStatusAnalysis::AssignAliases() { 782 void EscapeStatusAnalysis::AssignAliases() {
778 size_t max_size = 1024; 783 size_t max_size = 1024;
779 size_t min_size = 32; 784 size_t min_size = 32;
780 size_t stack_size = std::min( 785 size_t stack_size =
781 std::max( 786 std::min(std::max(graph()->NodeCount() / 5, min_size), max_size);
782 std::min(graph()->NodeCount() / 5, graph()->NodeCount() / 20 + 128),
783 min_size),
784 max_size);
785 stack_.reserve(stack_size); 787 stack_.reserve(stack_size);
786 ResizeStatusVector(); 788 ResizeStatusVector();
787 stack_.push_back(graph()->end()); 789 stack_.push_back(graph()->end());
788 CHECK_LT(graph()->NodeCount(), kUntrackable); 790 CHECK_LT(graph()->NodeCount(), kUntrackable);
789 aliases_.resize(graph()->NodeCount(), kNotReachable); 791 aliases_.resize(graph()->NodeCount(), kNotReachable);
790 aliases_[graph()->end()->id()] = kUntrackable; 792 aliases_[graph()->end()->id()] = kUntrackable;
791 status_stack_.reserve(8); 793 status_stack_.reserve(8);
792 TRACE("Discovering trackable nodes"); 794 TRACE("Discovering trackable nodes");
793 while (!stack_.empty()) { 795 while (!stack_.empty()) {
794 Node* node = stack_.back(); 796 Node* node = stack_.back();
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
994 case IrOpcode::kStoreElement: 996 case IrOpcode::kStoreElement:
995 case IrOpcode::kLoadElement: 997 case IrOpcode::kLoadElement:
996 case IrOpcode::kFrameState: 998 case IrOpcode::kFrameState:
997 case IrOpcode::kStateValues: 999 case IrOpcode::kStateValues:
998 case IrOpcode::kReferenceEqual: 1000 case IrOpcode::kReferenceEqual:
999 case IrOpcode::kFinishRegion: 1001 case IrOpcode::kFinishRegion:
1000 case IrOpcode::kObjectIsSmi: 1002 case IrOpcode::kObjectIsSmi:
1001 break; 1003 break;
1002 default: 1004 default:
1003 VirtualState* state = virtual_states_[node->id()]; 1005 VirtualState* state = virtual_states_[node->id()];
1004 if (VirtualObject* obj = ResolveVirtualObject(state, input)) { 1006 if (VirtualObject* obj =
1007 GetVirtualObject(state, ResolveReplacement(input))) {
1005 if (!obj->AllFieldsClear()) { 1008 if (!obj->AllFieldsClear()) {
1006 obj = CopyForModificationAt(obj, state, node); 1009 obj = CopyForModificationAt(obj, state, node);
1007 obj->ClearAllFields(); 1010 obj->ClearAllFields();
1008 TRACE("Cleared all fields of @%d:#%d\n", GetAlias(obj->id()), 1011 TRACE("Cleared all fields of @%d:#%d\n", GetAlias(obj->id()),
1009 obj->id()); 1012 obj->id());
1010 } 1013 }
1011 } 1014 }
1012 break; 1015 break;
1013 } 1016 }
1014 } 1017 }
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1106 } 1109 }
1107 TRACE(" %p (from %d %s)", static_cast<void*>(state), input->id(), 1110 TRACE(" %p (from %d %s)", static_cast<void*>(state), input->id(),
1108 input->op()->mnemonic()); 1111 input->op()->mnemonic());
1109 } 1112 }
1110 TRACE("\n"); 1113 TRACE("\n");
1111 1114
1112 if (cache_->states().size() == 0) { 1115 if (cache_->states().size() == 0) {
1113 return changed; 1116 return changed;
1114 } 1117 }
1115 1118
1116 changed = mergeState->MergeFrom(cache_, zone(), graph(), common(), 1119 changed =
1117 NodeProperties::GetControlInput(node), 1120 mergeState->MergeFrom(cache_, zone(), graph(), common(), node) || changed;
1118 node->op()->EffectInputCount()) ||
1119 changed;
1120 1121
1121 TRACE("Merge %s the node.\n", changed ? "changed" : "did not change"); 1122 TRACE("Merge %s the node.\n", changed ? "changed" : "did not change");
1122 1123
1123 if (changed) { 1124 if (changed) {
1124 status_analysis_.ResizeStatusVector(); 1125 status_analysis_.ResizeStatusVector();
1125 } 1126 }
1126 return changed; 1127 return changed;
1127 } 1128 }
1128 1129
1129 void EscapeAnalysis::ProcessAllocation(Node* node) { 1130 void EscapeAnalysis::ProcessAllocation(Node* node) {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1235 return status_analysis_.SetEscaped(node); 1236 return status_analysis_.SetEscaped(node);
1236 } 1237 }
1237 1238
1238 VirtualObject* EscapeAnalysis::GetVirtualObject(Node* at, NodeId id) { 1239 VirtualObject* EscapeAnalysis::GetVirtualObject(Node* at, NodeId id) {
1239 if (VirtualState* states = virtual_states_[at->id()]) { 1240 if (VirtualState* states = virtual_states_[at->id()]) {
1240 return states->VirtualObjectFromAlias(GetAlias(id)); 1241 return states->VirtualObjectFromAlias(GetAlias(id));
1241 } 1242 }
1242 return nullptr; 1243 return nullptr;
1243 } 1244 }
1244 1245
1245 VirtualObject* EscapeAnalysis::ResolveVirtualObject(VirtualState* state,
1246 Node* node) {
1247 return GetVirtualObject(state, ResolveReplacement(node));
1248 }
1249
1250 bool EscapeAnalysis::CompareVirtualObjects(Node* left, Node* right) { 1246 bool EscapeAnalysis::CompareVirtualObjects(Node* left, Node* right) {
1251 DCHECK(IsVirtual(left) && IsVirtual(right)); 1247 DCHECK(IsVirtual(left) && IsVirtual(right));
1252 left = ResolveReplacement(left); 1248 left = ResolveReplacement(left);
1253 right = ResolveReplacement(right); 1249 right = ResolveReplacement(right);
1254 if (IsEquivalentPhi(left, right)) { 1250 if (IsEquivalentPhi(left, right)) {
1255 return true; 1251 return true;
1256 } 1252 }
1257 return false; 1253 return false;
1258 } 1254 }
1259 1255
1260 int EscapeAnalysis::OffsetFromAccess(Node* node) { 1256 int EscapeAnalysis::OffsetFromAccess(Node* node) {
1261 DCHECK(OpParameter<FieldAccess>(node).offset % kPointerSize == 0); 1257 DCHECK(OpParameter<FieldAccess>(node).offset % kPointerSize == 0);
1262 return OpParameter<FieldAccess>(node).offset / kPointerSize; 1258 return OpParameter<FieldAccess>(node).offset / kPointerSize;
1263 } 1259 }
1264 1260
1265 void EscapeAnalysis::ProcessLoadFromPhi(int offset, Node* from, Node* node, 1261 void EscapeAnalysis::ProcessLoadFromPhi(int offset, Node* from, Node* load,
1266 VirtualState* state) { 1262 VirtualState* state) {
1267 TRACE("Load #%d from phi #%d", node->id(), from->id()); 1263 TRACE("Load #%d from phi #%d", load->id(), from->id());
1268 1264
1269 cache_->fields().clear(); 1265 cache_->fields().clear();
1270 for (int i = 0; i < node->op()->ValueInputCount(); ++i) { 1266 for (int i = 0; i < load->op()->ValueInputCount(); ++i) {
1271 Node* input = NodeProperties::GetValueInput(node, i); 1267 Node* input = NodeProperties::GetValueInput(load, i);
1272 cache_->fields().push_back(input); 1268 cache_->fields().push_back(input);
1273 } 1269 }
1274 1270
1275 cache_->LoadVirtualObjectsForFieldsFrom(state, 1271 cache_->LoadVirtualObjectsForFieldsFrom(state,
1276 status_analysis_.GetAliasMap()); 1272 status_analysis_.GetAliasMap());
1277 if (cache_->objects().size() == cache_->fields().size()) { 1273 if (cache_->objects().size() == cache_->fields().size()) {
1278 cache_->GetFields(offset); 1274 cache_->GetFields(offset);
1279 if (cache_->fields().size() == cache_->objects().size()) { 1275 if (cache_->fields().size() == cache_->objects().size()) {
1280 Node* rep = replacement(node); 1276 Node* rep = replacement(load);
1281 if (!rep || !IsEquivalentPhi(rep, cache_->fields())) { 1277 if (!rep || !IsEquivalentPhi(rep, cache_->fields())) {
1282 int value_input_count = static_cast<int>(cache_->fields().size()); 1278 int value_input_count = static_cast<int>(cache_->fields().size());
1283 cache_->fields().push_back(NodeProperties::GetControlInput(from)); 1279 cache_->fields().push_back(NodeProperties::GetControlInput(from));
1284 Node* phi = graph()->NewNode( 1280 Node* phi = graph()->NewNode(
1285 common()->Phi(MachineRepresentation::kTagged, value_input_count), 1281 common()->Phi(MachineRepresentation::kTagged, value_input_count),
1286 value_input_count + 1, &cache_->fields().front()); 1282 value_input_count + 1, &cache_->fields().front());
1287 status_analysis_.ResizeStatusVector(); 1283 status_analysis_.ResizeStatusVector();
1288 SetReplacement(node, phi); 1284 SetReplacement(load, phi);
1289 TRACE(" got phi created.\n"); 1285 TRACE(" got phi created.\n");
1290 } else { 1286 } else {
1291 TRACE(" has already phi #%d.\n", rep->id()); 1287 TRACE(" has already phi #%d.\n", rep->id());
1292 } 1288 }
1293 } else { 1289 } else {
1294 TRACE(" has incomplete field info.\n"); 1290 TRACE(" has incomplete field info.\n");
1295 } 1291 }
1296 } else { 1292 } else {
1297 TRACE(" has incomplete virtual object info.\n"); 1293 TRACE(" has incomplete virtual object info.\n");
1298 } 1294 }
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
1434 obj->id()); 1430 obj->id());
1435 } 1431 }
1436 } 1432 }
1437 } 1433 }
1438 } 1434 }
1439 1435
1440 Node* EscapeAnalysis::GetOrCreateObjectState(Node* effect, Node* node) { 1436 Node* EscapeAnalysis::GetOrCreateObjectState(Node* effect, Node* node) {
1441 if ((node->opcode() == IrOpcode::kFinishRegion || 1437 if ((node->opcode() == IrOpcode::kFinishRegion ||
1442 node->opcode() == IrOpcode::kAllocate) && 1438 node->opcode() == IrOpcode::kAllocate) &&
1443 IsVirtual(node)) { 1439 IsVirtual(node)) {
1444 if (VirtualObject* vobj = 1440 if (VirtualObject* vobj = GetVirtualObject(virtual_states_[effect->id()],
1445 ResolveVirtualObject(virtual_states_[effect->id()], node)) { 1441 ResolveReplacement(node))) {
1446 if (Node* object_state = vobj->GetObjectState()) { 1442 if (Node* object_state = vobj->GetObjectState()) {
1447 return object_state; 1443 return object_state;
1448 } else { 1444 } else {
1449 cache_->fields().clear(); 1445 cache_->fields().clear();
1450 for (size_t i = 0; i < vobj->field_count(); ++i) { 1446 for (size_t i = 0; i < vobj->field_count(); ++i) {
1451 if (Node* field = vobj->GetField(i)) { 1447 if (Node* field = vobj->GetField(i)) {
1452 cache_->fields().push_back(field); 1448 cache_->fields().push_back(field);
1453 } 1449 }
1454 } 1450 }
1455 int input_count = static_cast<int>(cache_->fields().size()); 1451 int input_count = static_cast<int>(cache_->fields().size());
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1529 return true; 1525 return true;
1530 } 1526 }
1531 } 1527 }
1532 } 1528 }
1533 return false; 1529 return false;
1534 } 1530 }
1535 1531
1536 } // namespace compiler 1532 } // namespace compiler
1537 } // namespace internal 1533 } // namespace internal
1538 } // namespace v8 1534 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/escape-analysis.h ('k') | src/compiler/escape-analysis-reducer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698