OLD | NEW |
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 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 return false; | 424 return false; |
425 } | 425 } |
426 for (size_t i = 0; i < inputs.size(); ++i) { | 426 for (size_t i = 0; i < inputs.size(); ++i) { |
427 Node* input = NodeProperties::GetValueInput(phi, static_cast<int>(i)); | 427 Node* input = NodeProperties::GetValueInput(phi, static_cast<int>(i)); |
428 if (!IsEquivalentPhi(input, inputs[i])) { | 428 if (!IsEquivalentPhi(input, inputs[i])) { |
429 return false; | 429 return false; |
430 } | 430 } |
431 } | 431 } |
432 return true; | 432 return true; |
433 } | 433 } |
434 | |
435 } // namespace | 434 } // namespace |
436 | 435 |
437 bool VirtualObject::MergeFields(size_t i, Node* at, MergeCache* cache, | 436 bool VirtualObject::MergeFields(size_t i, Node* at, MergeCache* cache, |
438 Graph* graph, CommonOperatorBuilder* common) { | 437 Graph* graph, CommonOperatorBuilder* common) { |
439 bool changed = false; | 438 bool changed = false; |
440 int value_input_count = static_cast<int>(cache->fields().size()); | 439 int value_input_count = static_cast<int>(cache->fields().size()); |
441 Node* rep = GetField(i); | 440 Node* rep = GetField(i); |
442 if (!rep || !IsCreatedPhi(i)) { | 441 if (!rep || !IsCreatedPhi(i)) { |
| 442 Type* phi_type = Type::None(); |
| 443 for (Node* input : cache->fields()) { |
| 444 CHECK_NOT_NULL(input); |
| 445 CHECK(!input->IsDead()); |
| 446 Type* input_type = NodeProperties::GetType(input); |
| 447 phi_type = Type::Union(phi_type, input_type, graph->zone()); |
| 448 } |
443 Node* control = NodeProperties::GetControlInput(at); | 449 Node* control = NodeProperties::GetControlInput(at); |
444 cache->fields().push_back(control); | 450 cache->fields().push_back(control); |
445 Node* phi = graph->NewNode( | 451 Node* phi = graph->NewNode( |
446 common->Phi(MachineRepresentation::kTagged, value_input_count), | 452 common->Phi(MachineRepresentation::kTagged, value_input_count), |
447 value_input_count + 1, &cache->fields().front()); | 453 value_input_count + 1, &cache->fields().front()); |
| 454 NodeProperties::SetType(phi, phi_type); |
448 SetField(i, phi, true); | 455 SetField(i, phi, true); |
| 456 |
449 #ifdef DEBUG | 457 #ifdef DEBUG |
450 if (FLAG_trace_turbo_escape) { | 458 if (FLAG_trace_turbo_escape) { |
451 PrintF(" Creating Phi #%d as merge of", phi->id()); | 459 PrintF(" Creating Phi #%d as merge of", phi->id()); |
452 for (int i = 0; i < value_input_count; i++) { | 460 for (int i = 0; i < value_input_count; i++) { |
453 PrintF(" #%d (%s)", cache->fields()[i]->id(), | 461 PrintF(" #%d (%s)", cache->fields()[i]->id(), |
454 cache->fields()[i]->op()->mnemonic()); | 462 cache->fields()[i]->op()->mnemonic()); |
455 } | 463 } |
456 PrintF("\n"); | 464 PrintF("\n"); |
457 } | 465 } |
458 #endif | 466 #endif |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
859 | 867 |
860 EscapeAnalysis::EscapeAnalysis(Graph* graph, CommonOperatorBuilder* common, | 868 EscapeAnalysis::EscapeAnalysis(Graph* graph, CommonOperatorBuilder* common, |
861 Zone* zone) | 869 Zone* zone) |
862 : zone_(zone), | 870 : zone_(zone), |
863 slot_not_analyzed_(graph->NewNode(common->NumberConstant(0x1c0debad))), | 871 slot_not_analyzed_(graph->NewNode(common->NumberConstant(0x1c0debad))), |
864 common_(common), | 872 common_(common), |
865 status_analysis_(new (zone) EscapeStatusAnalysis(this, graph, zone)), | 873 status_analysis_(new (zone) EscapeStatusAnalysis(this, graph, zone)), |
866 virtual_states_(zone), | 874 virtual_states_(zone), |
867 replacements_(zone), | 875 replacements_(zone), |
868 cycle_detection_(zone), | 876 cycle_detection_(zone), |
869 cache_(nullptr) {} | 877 cache_(nullptr) { |
| 878 // Type slot_not_analyzed_ manually. |
| 879 double v = OpParameter<double>(slot_not_analyzed_); |
| 880 NodeProperties::SetType(slot_not_analyzed_, Type::Range(v, v, zone)); |
| 881 } |
870 | 882 |
871 EscapeAnalysis::~EscapeAnalysis() {} | 883 EscapeAnalysis::~EscapeAnalysis() {} |
872 | 884 |
873 void EscapeAnalysis::Run() { | 885 void EscapeAnalysis::Run() { |
874 replacements_.resize(graph()->NodeCount()); | 886 replacements_.resize(graph()->NodeCount()); |
875 status_analysis_->AssignAliases(); | 887 status_analysis_->AssignAliases(); |
876 if (status_analysis_->AliasCount() > 0) { | 888 if (status_analysis_->AliasCount() > 0) { |
877 cache_ = new (zone()) MergeCache(zone()); | 889 cache_ = new (zone()) MergeCache(zone()); |
878 replacements_.resize(graph()->NodeCount()); | 890 replacements_.resize(graph()->NodeCount()); |
879 status_analysis_->ResizeStatusVector(); | 891 status_analysis_->ResizeStatusVector(); |
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1392 } | 1404 } |
1393 | 1405 |
1394 cache_->LoadVirtualObjectsForFieldsFrom(state, | 1406 cache_->LoadVirtualObjectsForFieldsFrom(state, |
1395 status_analysis_->GetAliasMap()); | 1407 status_analysis_->GetAliasMap()); |
1396 if (cache_->objects().size() == cache_->fields().size()) { | 1408 if (cache_->objects().size() == cache_->fields().size()) { |
1397 cache_->GetFields(offset); | 1409 cache_->GetFields(offset); |
1398 if (cache_->fields().size() == cache_->objects().size()) { | 1410 if (cache_->fields().size() == cache_->objects().size()) { |
1399 Node* rep = replacement(load); | 1411 Node* rep = replacement(load); |
1400 if (!rep || !IsEquivalentPhi(rep, cache_->fields())) { | 1412 if (!rep || !IsEquivalentPhi(rep, cache_->fields())) { |
1401 int value_input_count = static_cast<int>(cache_->fields().size()); | 1413 int value_input_count = static_cast<int>(cache_->fields().size()); |
| 1414 Type* phi_type = Type::None(); |
| 1415 for (Node* input : cache_->fields()) { |
| 1416 Type* input_type = NodeProperties::GetType(input); |
| 1417 phi_type = Type::Union(phi_type, input_type, graph()->zone()); |
| 1418 } |
1402 cache_->fields().push_back(NodeProperties::GetControlInput(from)); | 1419 cache_->fields().push_back(NodeProperties::GetControlInput(from)); |
1403 Node* phi = graph()->NewNode( | 1420 Node* phi = graph()->NewNode( |
1404 common()->Phi(MachineRepresentation::kTagged, value_input_count), | 1421 common()->Phi(MachineRepresentation::kTagged, value_input_count), |
1405 value_input_count + 1, &cache_->fields().front()); | 1422 value_input_count + 1, &cache_->fields().front()); |
| 1423 NodeProperties::SetType(phi, phi_type); |
1406 status_analysis_->ResizeStatusVector(); | 1424 status_analysis_->ResizeStatusVector(); |
1407 SetReplacement(load, phi); | 1425 SetReplacement(load, phi); |
1408 TRACE(" got phi created.\n"); | 1426 TRACE(" got phi created.\n"); |
1409 } else { | 1427 } else { |
1410 TRACE(" has already phi #%d.\n", rep->id()); | 1428 TRACE(" has already phi #%d.\n", rep->id()); |
1411 } | 1429 } |
1412 } else { | 1430 } else { |
1413 TRACE(" has incomplete field info.\n"); | 1431 TRACE(" has incomplete field info.\n"); |
1414 } | 1432 } |
1415 } else { | 1433 } else { |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1589 cache_->fields().clear(); | 1607 cache_->fields().clear(); |
1590 for (size_t i = 0; i < vobj->field_count(); ++i) { | 1608 for (size_t i = 0; i < vobj->field_count(); ++i) { |
1591 if (Node* field = vobj->GetField(i)) { | 1609 if (Node* field = vobj->GetField(i)) { |
1592 cache_->fields().push_back(ResolveReplacement(field)); | 1610 cache_->fields().push_back(ResolveReplacement(field)); |
1593 } | 1611 } |
1594 } | 1612 } |
1595 int input_count = static_cast<int>(cache_->fields().size()); | 1613 int input_count = static_cast<int>(cache_->fields().size()); |
1596 Node* new_object_state = | 1614 Node* new_object_state = |
1597 graph()->NewNode(common()->ObjectState(input_count), input_count, | 1615 graph()->NewNode(common()->ObjectState(input_count), input_count, |
1598 &cache_->fields().front()); | 1616 &cache_->fields().front()); |
| 1617 NodeProperties::SetType(new_object_state, Type::OtherInternal()); |
1599 vobj->SetObjectState(new_object_state); | 1618 vobj->SetObjectState(new_object_state); |
1600 TRACE( | 1619 TRACE( |
1601 "Creating object state #%d for vobj %p (from node #%d) at effect " | 1620 "Creating object state #%d for vobj %p (from node #%d) at effect " |
1602 "#%d\n", | 1621 "#%d\n", |
1603 new_object_state->id(), static_cast<void*>(vobj), node->id(), | 1622 new_object_state->id(), static_cast<void*>(vobj), node->id(), |
1604 effect->id()); | 1623 effect->id()); |
1605 // Now fix uses of other objects. | 1624 // Now fix uses of other objects. |
1606 for (size_t i = 0; i < vobj->field_count(); ++i) { | 1625 for (size_t i = 0; i < vobj->field_count(); ++i) { |
1607 if (Node* field = vobj->GetField(i)) { | 1626 if (Node* field = vobj->GetField(i)) { |
1608 if (Node* field_object_state = | 1627 if (Node* field_object_state = |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1688 } | 1707 } |
1689 } | 1708 } |
1690 return false; | 1709 return false; |
1691 } | 1710 } |
1692 | 1711 |
1693 Graph* EscapeAnalysis::graph() const { return status_analysis_->graph(); } | 1712 Graph* EscapeAnalysis::graph() const { return status_analysis_->graph(); } |
1694 | 1713 |
1695 } // namespace compiler | 1714 } // namespace compiler |
1696 } // namespace internal | 1715 } // namespace internal |
1697 } // namespace v8 | 1716 } // namespace v8 |
OLD | NEW |