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
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;
}
: 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) {
: 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) {
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());
}
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();
}
Bounds Typer::Visitor::TypeJSToObject(Node* node) {
- return Bounds(Type::None(zone()), Type::Object(zone()));
+ return Bounds(Type::None(zone()), Type::Receiver(zone()));
}
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();
}
Bounds Typer::Visitor::TypeJSStoreContext(Node* node) {
- return Bounds(Type::None(zone()));
+ UNREACHABLE();
+ return Bounds();
}
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();
}