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