| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/typer.h" | 5 #include "src/compiler/typer.h" |
| 6 | 6 |
| 7 #include <iomanip> |
| 8 |
| 7 #include "src/base/flags.h" | 9 #include "src/base/flags.h" |
| 8 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| 9 #include "src/compiler/common-operator.h" | 11 #include "src/compiler/common-operator.h" |
| 10 #include "src/compiler/graph-reducer.h" | 12 #include "src/compiler/graph-reducer.h" |
| 11 #include "src/compiler/js-operator.h" | 13 #include "src/compiler/js-operator.h" |
| 12 #include "src/compiler/loop-variable-optimizer.h" | 14 #include "src/compiler/loop-variable-optimizer.h" |
| 13 #include "src/compiler/node-properties.h" | 15 #include "src/compiler/node-properties.h" |
| 14 #include "src/compiler/node.h" | 16 #include "src/compiler/node.h" |
| 15 #include "src/compiler/operation-typer.h" | 17 #include "src/compiler/operation-typer.h" |
| 16 #include "src/compiler/simplified-operator.h" | 18 #include "src/compiler/simplified-operator.h" |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 if (induction_vars != nullptr) { | 332 if (induction_vars != nullptr) { |
| 331 induction_vars->ChangeToInductionVariablePhis(); | 333 induction_vars->ChangeToInductionVariablePhis(); |
| 332 } | 334 } |
| 333 Visitor visitor(this, induction_vars); | 335 Visitor visitor(this, induction_vars); |
| 334 GraphReducer graph_reducer(zone(), graph()); | 336 GraphReducer graph_reducer(zone(), graph()); |
| 335 graph_reducer.AddReducer(&visitor); | 337 graph_reducer.AddReducer(&visitor); |
| 336 for (Node* const root : roots) graph_reducer.ReduceNode(root); | 338 for (Node* const root : roots) graph_reducer.ReduceNode(root); |
| 337 graph_reducer.ReduceGraph(); | 339 graph_reducer.ReduceGraph(); |
| 338 | 340 |
| 339 if (induction_vars != nullptr) { | 341 if (induction_vars != nullptr) { |
| 340 induction_vars->ChangeFromInductionVariablePhis(); | 342 induction_vars->ChangeToPhisAndInsertGuards(); |
| 341 } | 343 } |
| 342 } | 344 } |
| 343 | 345 |
| 344 void Typer::Decorator::Decorate(Node* node) { | 346 void Typer::Decorator::Decorate(Node* node) { |
| 345 if (node->op()->ValueOutputCount() > 0) { | 347 if (node->op()->ValueOutputCount() > 0) { |
| 346 // Only eagerly type-decorate nodes with known input types. | 348 // Only eagerly type-decorate nodes with known input types. |
| 347 // Other cases will generally require a proper fixpoint iteration with Run. | 349 // Other cases will generally require a proper fixpoint iteration with Run. |
| 348 bool is_typed = NodeProperties::IsTyped(node); | 350 bool is_typed = NodeProperties::IsTyped(node); |
| 349 if (is_typed || NodeProperties::AllValueInputsAreTyped(node)) { | 351 if (is_typed || NodeProperties::AllValueInputsAreTyped(node)) { |
| 350 Visitor typing(typer_, nullptr); | 352 Visitor typing(typer_, nullptr); |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 } | 690 } |
| 689 // The lower bound must be at most the initial value's lower bound. | 691 // The lower bound must be at most the initial value's lower bound. |
| 690 min = std::min(min, initial_type->Min()); | 692 min = std::min(min, initial_type->Min()); |
| 691 } else { | 693 } else { |
| 692 // Shortcut: If the increment can be both positive and negative, | 694 // Shortcut: If the increment can be both positive and negative, |
| 693 // the variable can go arbitrarily far, so just return integer. | 695 // the variable can go arbitrarily far, so just return integer. |
| 694 return typer_->cache_.kInteger; | 696 return typer_->cache_.kInteger; |
| 695 } | 697 } |
| 696 if (FLAG_trace_turbo_loop) { | 698 if (FLAG_trace_turbo_loop) { |
| 697 OFStream os(stdout); | 699 OFStream os(stdout); |
| 700 os << std::setprecision(10); |
| 698 os << "Loop (" << NodeProperties::GetControlInput(node)->id() | 701 os << "Loop (" << NodeProperties::GetControlInput(node)->id() |
| 699 << ") variable bounds for phi " << node->id() << ": (" << min << ", " | 702 << ") variable bounds for phi " << node->id() << ": (" << min << ", " |
| 700 << max << ")\n"; | 703 << max << ")\n"; |
| 701 } | 704 } |
| 702 return Type::Range(min, max, typer_->zone()); | 705 return Type::Range(min, max, typer_->zone()); |
| 703 } | 706 } |
| 704 | 707 |
| 705 Type* Typer::Visitor::TypeEffectPhi(Node* node) { | 708 Type* Typer::Visitor::TypeEffectPhi(Node* node) { |
| 706 UNREACHABLE(); | 709 UNREACHABLE(); |
| 707 return nullptr; | 710 return nullptr; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 758 Type* Typer::Visitor::TypeProjection(Node* node) { | 761 Type* Typer::Visitor::TypeProjection(Node* node) { |
| 759 Type* const type = Operand(node, 0); | 762 Type* const type = Operand(node, 0); |
| 760 if (type->Is(Type::None())) return Type::None(); | 763 if (type->Is(Type::None())) return Type::None(); |
| 761 int const index = static_cast<int>(ProjectionIndexOf(node->op())); | 764 int const index = static_cast<int>(ProjectionIndexOf(node->op())); |
| 762 if (type->IsTuple() && index < type->AsTuple()->Arity()) { | 765 if (type->IsTuple() && index < type->AsTuple()->Arity()) { |
| 763 return type->AsTuple()->Element(index); | 766 return type->AsTuple()->Element(index); |
| 764 } | 767 } |
| 765 return Type::Any(); | 768 return Type::Any(); |
| 766 } | 769 } |
| 767 | 770 |
| 771 Type* Typer::Visitor::TypeTypeGuard(Node* node) { |
| 772 Type* const type = Operand(node, 0); |
| 773 return typer_->operation_typer()->TypeTypeGuard(node->op(), type); |
| 774 } |
| 775 |
| 768 Type* Typer::Visitor::TypeDead(Node* node) { return Type::None(); } | 776 Type* Typer::Visitor::TypeDead(Node* node) { return Type::None(); } |
| 769 | 777 |
| 770 // JS comparison operators. | 778 // JS comparison operators. |
| 771 | 779 |
| 772 | 780 |
| 773 Type* Typer::Visitor::JSEqualTyper(Type* lhs, Type* rhs, Typer* t) { | 781 Type* Typer::Visitor::JSEqualTyper(Type* lhs, Type* rhs, Typer* t) { |
| 774 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false_; | 782 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false_; |
| 775 if (lhs->Is(Type::NullOrUndefined()) && rhs->Is(Type::NullOrUndefined())) { | 783 if (lhs->Is(Type::NullOrUndefined()) && rhs->Is(Type::NullOrUndefined())) { |
| 776 return t->singleton_true_; | 784 return t->singleton_true_; |
| 777 } | 785 } |
| (...skipping 1514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2292 } | 2300 } |
| 2293 if (Type::IsInteger(*value)) { | 2301 if (Type::IsInteger(*value)) { |
| 2294 return Type::Range(value->Number(), value->Number(), zone()); | 2302 return Type::Range(value->Number(), value->Number(), zone()); |
| 2295 } | 2303 } |
| 2296 return Type::Constant(value, zone()); | 2304 return Type::Constant(value, zone()); |
| 2297 } | 2305 } |
| 2298 | 2306 |
| 2299 } // namespace compiler | 2307 } // namespace compiler |
| 2300 } // namespace internal | 2308 } // namespace internal |
| 2301 } // namespace v8 | 2309 } // namespace v8 |
| OLD | NEW |