Commit f3e03388 authored by rossberg@chromium.org's avatar rossberg@chromium.org

Couple of fixes to typer

(Extracted from verifier CL.)

R=mstarzinger@chromium.org
BUG=

Review URL: https://codereview.chromium.org/554763003

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23801 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 5cc34b6b
...@@ -6,11 +6,9 @@ ...@@ -6,11 +6,9 @@
#define V8_COMPILER_OPCODES_H_ #define V8_COMPILER_OPCODES_H_
// Opcodes for control operators. // Opcodes for control operators.
#define CONTROL_OP_LIST(V) \ #define INNER_CONTROL_OP_LIST(V) \
V(Start) \
V(Dead) \ V(Dead) \
V(Loop) \ V(Loop) \
V(End) \
V(Branch) \ V(Branch) \
V(IfTrue) \ V(IfTrue) \
V(IfFalse) \ V(IfFalse) \
...@@ -18,6 +16,11 @@ ...@@ -18,6 +16,11 @@
V(Return) \ V(Return) \
V(Throw) V(Throw)
#define CONTROL_OP_LIST(V) \
INNER_CONTROL_OP_LIST(V) \
V(Start) \
V(End)
// Opcodes for common operators. // Opcodes for common operators.
#define LEAF_OP_LIST(V) \ #define LEAF_OP_LIST(V) \
V(Int32Constant) \ V(Int32Constant) \
...@@ -83,7 +86,8 @@ ...@@ -83,7 +86,8 @@
V(JSToName) \ V(JSToName) \
V(JSToObject) V(JSToObject)
#define JS_OTHER_UNOP_LIST(V) V(JSTypeOf) #define JS_OTHER_UNOP_LIST(V) \
V(JSTypeOf)
#define JS_SIMPLE_UNOP_LIST(V) \ #define JS_SIMPLE_UNOP_LIST(V) \
JS_LOGIC_UNOP_LIST(V) \ JS_LOGIC_UNOP_LIST(V) \
......
...@@ -70,21 +70,25 @@ class Typer::Visitor : public NullNodeVisitor { ...@@ -70,21 +70,25 @@ class Typer::Visitor : public NullNodeVisitor {
Bounds TypeNode(Node* node) { Bounds TypeNode(Node* node) {
switch (node->opcode()) { switch (node->opcode()) {
#define DECLARE_CASE(x) case IrOpcode::k##x: return Type##x(node); #define DECLARE_CASE(x) case IrOpcode::k##x: return Type##x(node);
DECLARE_CASE(Start)
VALUE_OP_LIST(DECLARE_CASE) VALUE_OP_LIST(DECLARE_CASE)
#undef DECLARE_CASE #undef DECLARE_CASE
#define DECLARE_CASE(x) case IrOpcode::k##x: #define DECLARE_CASE(x) case IrOpcode::k##x:
CONTROL_OP_LIST(DECLARE_CASE) DECLARE_CASE(End)
INNER_CONTROL_OP_LIST(DECLARE_CASE)
#undef DECLARE_CASE #undef DECLARE_CASE
break; break;
} }
return Bounds(Type::None(zone())); UNREACHABLE();
return Bounds();
} }
Type* TypeConstant(Handle<Object> value); Type* TypeConstant(Handle<Object> value);
protected: protected:
#define DECLARE_METHOD(x) inline Bounds Type##x(Node* node); #define DECLARE_METHOD(x) inline Bounds Type##x(Node* node);
DECLARE_METHOD(Start)
VALUE_OP_LIST(DECLARE_METHOD) VALUE_OP_LIST(DECLARE_METHOD)
#undef DECLARE_METHOD #undef DECLARE_METHOD
...@@ -118,12 +122,11 @@ class Typer::RunVisitor : public Typer::Visitor { ...@@ -118,12 +122,11 @@ class Typer::RunVisitor : public Typer::Visitor {
phis(NodeSet::key_compare(), NodeSet::allocator_type(typer->zone())) {} phis(NodeSet::key_compare(), NodeSet::allocator_type(typer->zone())) {}
GenericGraphVisit::Control Post(Node* node) { GenericGraphVisit::Control Post(Node* node) {
Bounds bounds = TypeNode(node); if (OperatorProperties::HasValueOutput(node->op())) {
if (node->opcode() == IrOpcode::kPhi) { Bounds bounds = TypeNode(node);
// Remember phis for least fixpoint iteration.
phis.insert(node);
} else {
NodeProperties::SetBounds(node, bounds); NodeProperties::SetBounds(node, bounds);
// Remember phis for least fixpoint iteration.
if (node->opcode() == IrOpcode::kPhi) phis.insert(node);
} }
return GenericGraphVisit::CONTINUE; return GenericGraphVisit::CONTINUE;
} }
...@@ -138,13 +141,17 @@ class Typer::NarrowVisitor : public Typer::Visitor { ...@@ -138,13 +141,17 @@ class Typer::NarrowVisitor : public Typer::Visitor {
: Visitor(typer, context) {} : Visitor(typer, context) {}
GenericGraphVisit::Control Pre(Node* node) { GenericGraphVisit::Control Pre(Node* node) {
Bounds previous = NodeProperties::GetBounds(node); if (OperatorProperties::HasValueOutput(node->op())) {
Bounds bounds = TypeNode(node); Bounds previous = NodeProperties::GetBounds(node);
NodeProperties::SetBounds(node, Bounds::Both(bounds, previous, zone())); Bounds bounds = TypeNode(node);
DCHECK(bounds.Narrows(previous)); NodeProperties::SetBounds(node, Bounds::Both(bounds, previous, zone()));
// Stop when nothing changed (but allow reentry in case it does later). DCHECK(bounds.Narrows(previous));
return previous.Narrows(bounds) // Stop when nothing changed (but allow re-entry in case it does later).
? GenericGraphVisit::DEFER : GenericGraphVisit::REENTER; return previous.Narrows(bounds)
? GenericGraphVisit::DEFER : GenericGraphVisit::REENTER;
} else {
return GenericGraphVisit::SKIP;
}
} }
GenericGraphVisit::Control Post(Node* node) { GenericGraphVisit::Control Post(Node* node) {
...@@ -159,14 +166,18 @@ class Typer::WidenVisitor : public Typer::Visitor { ...@@ -159,14 +166,18 @@ class Typer::WidenVisitor : public Typer::Visitor {
: Visitor(typer, context) {} : Visitor(typer, context) {}
GenericGraphVisit::Control Pre(Node* node) { GenericGraphVisit::Control Pre(Node* node) {
Bounds previous = NodeProperties::GetBounds(node); if (OperatorProperties::HasValueOutput(node->op())) {
Bounds bounds = TypeNode(node); Bounds previous = NodeProperties::GetBounds(node);
DCHECK(previous.lower->Is(bounds.lower)); Bounds bounds = TypeNode(node);
DCHECK(previous.upper->Is(bounds.upper)); DCHECK(previous.lower->Is(bounds.lower));
NodeProperties::SetBounds(node, bounds); // TODO(rossberg): Either? DCHECK(previous.upper->Is(bounds.upper));
// Stop when nothing changed (but allow reentry in case it does later). NodeProperties::SetBounds(node, bounds); // TODO(rossberg): Either?
return bounds.Narrows(previous) // Stop when nothing changed (but allow re-entry in case it does later).
? GenericGraphVisit::DEFER : GenericGraphVisit::REENTER; return bounds.Narrows(previous)
? GenericGraphVisit::DEFER : GenericGraphVisit::REENTER;
} else {
return GenericGraphVisit::SKIP;
}
} }
GenericGraphVisit::Control Post(Node* node) { GenericGraphVisit::Control Post(Node* node) {
...@@ -198,13 +209,26 @@ void Typer::Widen(Graph* graph, Node* start, MaybeHandle<Context> context) { ...@@ -198,13 +209,26 @@ void Typer::Widen(Graph* graph, Node* start, MaybeHandle<Context> context) {
void Typer::Init(Node* node) { void Typer::Init(Node* node) {
Visitor typing(this, MaybeHandle<Context>()); if (OperatorProperties::HasValueOutput(node->op())) {
Bounds bounds = typing.TypeNode(node); Visitor typing(this, MaybeHandle<Context>());
NodeProperties::SetBounds(node, bounds); Bounds bounds = typing.TypeNode(node);
NodeProperties::SetBounds(node, bounds);
}
}
// -----------------------------------------------------------------------------
// Control operators.
Bounds Typer::Visitor::TypeStart(Node* node) {
return Bounds(Type::Internal(zone()));
} }
// Common operators. // Common operators.
Bounds Typer::Visitor::TypeParameter(Node* node) { Bounds Typer::Visitor::TypeParameter(Node* node) {
return Bounds::Unbounded(zone()); return Bounds::Unbounded(zone());
} }
...@@ -256,30 +280,37 @@ Bounds Typer::Visitor::TypePhi(Node* node) { ...@@ -256,30 +280,37 @@ Bounds Typer::Visitor::TypePhi(Node* node) {
Bounds Typer::Visitor::TypeEffectPhi(Node* node) { Bounds Typer::Visitor::TypeEffectPhi(Node* node) {
return Bounds(Type::None(zone())); UNREACHABLE();
return Bounds();
} }
Bounds Typer::Visitor::TypeControlEffect(Node* node) { Bounds Typer::Visitor::TypeControlEffect(Node* node) {
return Bounds(Type::None(zone())); UNREACHABLE();
return Bounds();
} }
Bounds Typer::Visitor::TypeValueEffect(Node* node) { Bounds Typer::Visitor::TypeValueEffect(Node* node) {
return Bounds(Type::None(zone())); UNREACHABLE();
return Bounds();
} }
Bounds Typer::Visitor::TypeFinish(Node* node) { return OperandType(node, 0); } Bounds Typer::Visitor::TypeFinish(Node* node) {
return OperandType(node, 0);
}
Bounds Typer::Visitor::TypeFrameState(Node* node) { Bounds Typer::Visitor::TypeFrameState(Node* node) {
return Bounds(Type::None(zone())); UNREACHABLE();
return Bounds();
} }
Bounds Typer::Visitor::TypeStateValues(Node* node) { Bounds Typer::Visitor::TypeStateValues(Node* node) {
return Bounds(Type::None(zone())); UNREACHABLE();
return Bounds();
} }
...@@ -424,7 +455,7 @@ Bounds Typer::Visitor::TypeJSToName(Node* node) { ...@@ -424,7 +455,7 @@ Bounds Typer::Visitor::TypeJSToName(Node* node) {
Bounds Typer::Visitor::TypeJSToObject(Node* node) { Bounds Typer::Visitor::TypeJSToObject(Node* node) {
return Bounds(Type::None(zone()), Type::Object(zone())); return Bounds(Type::None(zone()), Type::Receiver(zone()));
} }
...@@ -458,12 +489,14 @@ Bounds Typer::Visitor::TypeJSLoadNamed(Node* node) { ...@@ -458,12 +489,14 @@ Bounds Typer::Visitor::TypeJSLoadNamed(Node* node) {
Bounds Typer::Visitor::TypeJSStoreProperty(Node* node) { Bounds Typer::Visitor::TypeJSStoreProperty(Node* node) {
return Bounds(Type::None(zone())); UNREACHABLE();
return Bounds();
} }
Bounds Typer::Visitor::TypeJSStoreNamed(Node* node) { Bounds Typer::Visitor::TypeJSStoreNamed(Node* node) {
return Bounds(Type::None(zone())); UNREACHABLE();
return Bounds();
} }
...@@ -523,7 +556,8 @@ Bounds Typer::Visitor::TypeJSLoadContext(Node* node) { ...@@ -523,7 +556,8 @@ Bounds Typer::Visitor::TypeJSLoadContext(Node* node) {
Bounds Typer::Visitor::TypeJSStoreContext(Node* node) { Bounds Typer::Visitor::TypeJSStoreContext(Node* node) {
return Bounds(Type::None(zone())); UNREACHABLE();
return Bounds();
} }
...@@ -744,12 +778,14 @@ Bounds Typer::Visitor::TypeLoadElement(Node* node) { ...@@ -744,12 +778,14 @@ Bounds Typer::Visitor::TypeLoadElement(Node* node) {
Bounds Typer::Visitor::TypeStoreField(Node* node) { Bounds Typer::Visitor::TypeStoreField(Node* node) {
return Bounds(Type::None()); UNREACHABLE();
return Bounds();
} }
Bounds Typer::Visitor::TypeStoreElement(Node* node) { Bounds Typer::Visitor::TypeStoreElement(Node* node) {
return Bounds(Type::None()); UNREACHABLE();
return Bounds();
} }
......
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