Commit 3f3bacc3 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Assign proper types to Parameter nodes.

R=epertoso@chromium.org

Review-Url: https://codereview.chromium.org/2223873002
Cr-Commit-Position: refs/heads/master@{#40695}
parent 24b1c1ab
...@@ -868,7 +868,7 @@ struct OsrTyperPhase { ...@@ -868,7 +868,7 @@ struct OsrTyperPhase {
// to compute loop variable bounds on OSR. // to compute loop variable bounds on OSR.
LoopVariableOptimizer induction_vars(data->jsgraph()->graph(), LoopVariableOptimizer induction_vars(data->jsgraph()->graph(),
data->common(), temp_zone); data->common(), temp_zone);
Typer typer(data->isolate(), data->graph()); Typer typer(data->isolate(), Typer::kNoFlags, data->graph());
typer.Run(roots, &induction_vars); typer.Run(roots, &induction_vars);
} }
}; };
...@@ -1545,10 +1545,22 @@ bool PipelineImpl::CreateGraph() { ...@@ -1545,10 +1545,22 @@ bool PipelineImpl::CreateGraph() {
// Run the type-sensitive lowerings and optimizations on the graph. // Run the type-sensitive lowerings and optimizations on the graph.
{ {
// Determine the Typer operation flags.
Typer::Flags flags = Typer::kNoFlags;
if (is_sloppy(info()->shared_info()->language_mode()) &&
!info()->shared_info()->IsBuiltin()) {
// Sloppy mode functions always have an Object for this.
flags |= Typer::kThisIsReceiver;
}
if (IsClassConstructor(info()->shared_info()->kind())) {
// Class constructors cannot be [[Call]]ed.
flags |= Typer::kNewTargetIsReceiver;
}
// Type the graph and keep the Typer running on newly created nodes within // Type the graph and keep the Typer running on newly created nodes within
// this scope; the Typer is automatically unlinked from the Graph once we // this scope; the Typer is automatically unlinked from the Graph once we
// leave this scope below. // leave this scope below.
Typer typer(isolate(), data->graph()); Typer typer(isolate(), flags, data->graph());
Run<TyperPhase>(&typer); Run<TyperPhase>(&typer);
RunPrintAndVerify("Typed"); RunPrintAndVerify("Typed");
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "src/compiler/common-operator.h" #include "src/compiler/common-operator.h"
#include "src/compiler/graph-reducer.h" #include "src/compiler/graph-reducer.h"
#include "src/compiler/js-operator.h" #include "src/compiler/js-operator.h"
#include "src/compiler/linkage.h"
#include "src/compiler/loop-variable-optimizer.h" #include "src/compiler/loop-variable-optimizer.h"
#include "src/compiler/node-properties.h" #include "src/compiler/node-properties.h"
#include "src/compiler/node.h" #include "src/compiler/node.h"
...@@ -32,8 +33,9 @@ class Typer::Decorator final : public GraphDecorator { ...@@ -32,8 +33,9 @@ class Typer::Decorator final : public GraphDecorator {
Typer* const typer_; Typer* const typer_;
}; };
Typer::Typer(Isolate* isolate, Graph* graph) Typer::Typer(Isolate* isolate, Flags flags, Graph* graph)
: isolate_(isolate), : isolate_(isolate),
flags_(flags),
graph_(graph), graph_(graph),
decorator_(nullptr), decorator_(nullptr),
cache_(TypeCache::Get()), cache_(TypeCache::Get()),
...@@ -546,7 +548,34 @@ Type* Typer::Visitor::TypeIfException(Node* node) { ...@@ -546,7 +548,34 @@ Type* Typer::Visitor::TypeIfException(Node* node) {
// Common operators. // Common operators.
Type* Typer::Visitor::TypeParameter(Node* node) { return Type::Any(); } Type* Typer::Visitor::TypeParameter(Node* node) {
Node* const start = node->InputAt(0);
DCHECK_EQ(IrOpcode::kStart, start->opcode());
int const parameter_count = start->op()->ValueOutputCount() - 4;
DCHECK_LE(1, parameter_count);
int const index = ParameterIndexOf(node->op());
if (index == Linkage::kJSCallClosureParamIndex) {
return Type::Function();
} else if (index == 0) {
if (typer_->flags() & Typer::kThisIsReceiver) {
return Type::Receiver();
} else {
// Parameter[this] can be the_hole for derived class constructors.
return Type::Union(Type::Hole(), Type::NonInternal(), typer_->zone());
}
} else if (index == Linkage::GetJSCallNewTargetParamIndex(parameter_count)) {
if (typer_->flags() & Typer::kNewTargetIsReceiver) {
return Type::Receiver();
} else {
return Type::Union(Type::Receiver(), Type::Undefined(), typer_->zone());
}
} else if (index == Linkage::GetJSCallArgCountParamIndex(parameter_count)) {
return Type::Range(0.0, Code::kMaxArguments, typer_->zone());
} else if (index == Linkage::GetJSCallContextParamIndex(parameter_count)) {
return Type::OtherInternal();
}
return Type::NonInternal();
}
Type* Typer::Visitor::TypeOsrValue(Node* node) { return Type::Any(); } Type* Typer::Visitor::TypeOsrValue(Node* node) { return Type::Any(); }
......
...@@ -18,7 +18,14 @@ class LoopVariableOptimizer; ...@@ -18,7 +18,14 @@ class LoopVariableOptimizer;
class V8_EXPORT_PRIVATE Typer { class V8_EXPORT_PRIVATE Typer {
public: public:
Typer(Isolate* isolate, Graph* graph); enum Flag : uint8_t {
kNoFlags = 0,
kThisIsReceiver = 1u << 0, // Parameter this is an Object.
kNewTargetIsReceiver = 1u << 1, // Parameter new.target is an Object.
};
typedef base::Flags<Flag> Flags;
Typer(Isolate* isolate, Flags flags, Graph* graph);
~Typer(); ~Typer();
void Run(); void Run();
...@@ -30,12 +37,14 @@ class V8_EXPORT_PRIVATE Typer { ...@@ -30,12 +37,14 @@ class V8_EXPORT_PRIVATE Typer {
class Visitor; class Visitor;
class Decorator; class Decorator;
Flags flags() const { return flags_; }
Graph* graph() const { return graph_; } Graph* graph() const { return graph_; }
Zone* zone() const { return graph()->zone(); } Zone* zone() const { return graph()->zone(); }
Isolate* isolate() const { return isolate_; } Isolate* isolate() const { return isolate_; }
OperationTyper* operation_typer() { return &operation_typer_; } OperationTyper* operation_typer() { return &operation_typer_; }
Isolate* const isolate_; Isolate* const isolate_;
Flags const flags_;
Graph* const graph_; Graph* const graph_;
Decorator* decorator_; Decorator* decorator_;
TypeCache const& cache_; TypeCache const& cache_;
...@@ -50,6 +59,8 @@ class V8_EXPORT_PRIVATE Typer { ...@@ -50,6 +59,8 @@ class V8_EXPORT_PRIVATE Typer {
DISALLOW_COPY_AND_ASSIGN(Typer); DISALLOW_COPY_AND_ASSIGN(Typer);
}; };
DEFINE_OPERATORS_FOR_FLAGS(Typer::Flags);
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -38,7 +38,7 @@ class JSTypedLoweringTester : public HandleAndZoneScope { ...@@ -38,7 +38,7 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
common(main_zone()), common(main_zone()),
deps(main_isolate(), main_zone()), deps(main_isolate(), main_zone()),
graph(main_zone()), graph(main_zone()),
typer(main_isolate(), &graph), typer(main_isolate(), Typer::kNoFlags, &graph),
context_node(NULL), context_node(NULL),
flags(flags) { flags(flags) {
graph.SetStart(graph.NewNode(common.Start(num_parameters))); graph.SetStart(graph.NewNode(common.Start(num_parameters)));
......
...@@ -103,10 +103,8 @@ Matcher<Node*> GraphTest::IsUndefinedConstant() { ...@@ -103,10 +103,8 @@ Matcher<Node*> GraphTest::IsUndefinedConstant() {
return IsHeapConstant(factory()->undefined_value()); return IsHeapConstant(factory()->undefined_value());
} }
TypedGraphTest::TypedGraphTest(int num_parameters) TypedGraphTest::TypedGraphTest(int num_parameters)
: GraphTest(num_parameters), typer_(isolate(), graph()) {} : GraphTest(num_parameters), typer_(isolate(), Typer::kNoFlags, graph()) {}
TypedGraphTest::~TypedGraphTest() {} TypedGraphTest::~TypedGraphTest() {}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment