| Index: src/compiler/verifier.cc
 | 
| diff --git a/src/compiler/verifier.cc b/src/compiler/verifier.cc
 | 
| index f2ad4bae70c330b8960c96ff2b01d496c23fb9d6..6887d5c465a05bfb8be0fdb800460cc750eeb262 100644
 | 
| --- a/src/compiler/verifier.cc
 | 
| +++ b/src/compiler/verifier.cc
 | 
| @@ -56,10 +56,8 @@ class Verifier::Visitor : public NullNodeVisitor {
 | 
|  
 | 
|   private:
 | 
|    // TODO(rossberg): Get rid of these once we got rid of NodeProperties.
 | 
| -  Bounds bounds(Node* node) {
 | 
| -    return NodeProperties::GetBounds(node);
 | 
| -  }
 | 
| -  Node* Operand(Node* node, int i = 0) {
 | 
| +  Bounds bounds(Node* node) { return NodeProperties::GetBounds(node); }
 | 
| +  Node* ValueInput(Node* node, int i = 0) {
 | 
|      return NodeProperties::GetValueInput(node, i);
 | 
|    }
 | 
|    FieldAccess Field(Node* node) {
 | 
| @@ -72,6 +70,16 @@ class Verifier::Visitor : public NullNodeVisitor {
 | 
|             node->opcode() == IrOpcode::kStoreElement);
 | 
|      return OpParameter<ElementAccess>(node);
 | 
|    }
 | 
| +  void CheckNotTyped(Node* node) { CHECK(!NodeProperties::IsTyped(node)); }
 | 
| +  void CheckUpperIs(Node* node, Type* type) {
 | 
| +    if (typing == TYPED) CHECK(bounds(node).upper->Is(type));
 | 
| +  }
 | 
| +  void CheckUpperMaybe(Node* node, Type* type) {
 | 
| +    if (typing == TYPED) CHECK(bounds(node).upper->Maybe(type));
 | 
| +  }
 | 
| +  void CheckValueInputIs(Node* node, int i, Type* type) {
 | 
| +    if (typing == TYPED) CHECK(bounds(ValueInput(node, i)).upper->Is(type));
 | 
| +  }
 | 
|  };
 | 
|  
 | 
|  
 | 
| @@ -141,527 +149,532 @@ GenericGraphVisit::Control Verifier::Visitor::Pre(Node* node) {
 | 
|      }
 | 
|    }
 | 
|  
 | 
| -  if (typing == TYPED) {
 | 
| -    switch (node->opcode()) {
 | 
| -      // Control operators
 | 
| -      // -----------------
 | 
| -      case IrOpcode::kStart:
 | 
| -        // Start has no inputs.
 | 
| -        CHECK_EQ(0, input_count);
 | 
| -        // Type is a tuple.
 | 
| -        // TODO(rossberg): Multiple outputs are currently typed as Internal.
 | 
| -        CHECK(bounds(node).upper->Is(Type::Internal()));
 | 
| -        break;
 | 
| -      case IrOpcode::kEnd:
 | 
| -        // End has no outputs.
 | 
| -        CHECK(!OperatorProperties::HasValueOutput(node->op()));
 | 
| -        CHECK(!OperatorProperties::HasEffectOutput(node->op()));
 | 
| -        CHECK(!OperatorProperties::HasControlOutput(node->op()));
 | 
| -        // Type is empty.
 | 
| -        CHECK(!NodeProperties::IsTyped(node));
 | 
| -        break;
 | 
| -      case IrOpcode::kDead:
 | 
| -        // Dead is never connected to the graph.
 | 
| -        UNREACHABLE();
 | 
| -      case IrOpcode::kBranch: {
 | 
| -        // Branch uses are IfTrue and IfFalse.
 | 
| -        Node::Uses uses = node->uses();
 | 
| -        int count_true = 0, count_false = 0;
 | 
| -        for (Node::Uses::iterator it = uses.begin(); it != uses.end(); ++it) {
 | 
| -          CHECK((*it)->opcode() == IrOpcode::kIfTrue ||
 | 
| -                (*it)->opcode() == IrOpcode::kIfFalse);
 | 
| -          if ((*it)->opcode() == IrOpcode::kIfTrue) ++count_true;
 | 
| -          if ((*it)->opcode() == IrOpcode::kIfFalse) ++count_false;
 | 
| -        }
 | 
| -        CHECK(count_true == 1 && count_false == 1);
 | 
| -        // Type is empty.
 | 
| -        CHECK(!NodeProperties::IsTyped(node));
 | 
| -        break;
 | 
| -      }
 | 
| -      case IrOpcode::kIfTrue:
 | 
| -      case IrOpcode::kIfFalse:
 | 
| -        CHECK_EQ(IrOpcode::kBranch,
 | 
| -                 NodeProperties::GetControlInput(node, 0)->opcode());
 | 
| -        // Type is empty.
 | 
| -        CHECK(!NodeProperties::IsTyped(node));
 | 
| -        break;
 | 
| -      case IrOpcode::kLoop:
 | 
| -      case IrOpcode::kMerge:
 | 
| -        // Type is empty.
 | 
| -        CHECK(!NodeProperties::IsTyped(node));
 | 
| -        break;
 | 
| -      case IrOpcode::kReturn:
 | 
| -        // TODO(rossberg): check successor is End
 | 
| -        // Type is empty.
 | 
| -        CHECK(!NodeProperties::IsTyped(node));
 | 
| -        break;
 | 
| -      case IrOpcode::kThrow:
 | 
| -        // TODO(rossberg): what are the constraints on these?
 | 
| -        // Type is empty.
 | 
| -        CHECK(!NodeProperties::IsTyped(node));
 | 
| -        break;
 | 
| -
 | 
| -      // Common operators
 | 
| -      // ----------------
 | 
| -      case IrOpcode::kParameter: {
 | 
| -        // Parameters have the start node as inputs.
 | 
| -        CHECK_EQ(1, input_count);
 | 
| -        CHECK_EQ(IrOpcode::kStart,
 | 
| -                 NodeProperties::GetValueInput(node, 0)->opcode());
 | 
| -        // Parameter has an input that produces enough values.
 | 
| -        int index = OpParameter<int>(node);
 | 
| -        Node* input = NodeProperties::GetValueInput(node, 0);
 | 
| -        // Currently, parameter indices start at -1 instead of 0.
 | 
| -        CHECK_GT(
 | 
| -            OperatorProperties::GetValueOutputCount(input->op()), index + 1);
 | 
| -        // Type can be anything.
 | 
| -        CHECK(bounds(node).upper->Is(Type::Any()));
 | 
| -        break;
 | 
| -      }
 | 
| -      case IrOpcode::kInt32Constant:  // TODO(rossberg): rename Word32Constant?
 | 
| -        // Constants have no inputs.
 | 
| -        CHECK_EQ(0, input_count);
 | 
| -        // Type is a 32 bit integer, signed or unsigned.
 | 
| -        CHECK(bounds(node).upper->Is(Type::Integral32()));
 | 
| -        break;
 | 
| -      case IrOpcode::kInt64Constant:
 | 
| -        // Constants have no inputs.
 | 
| -        CHECK_EQ(0, input_count);
 | 
| -        // Type is internal.
 | 
| -        // TODO(rossberg): Introduce proper Int64 type.
 | 
| -        CHECK(bounds(node).upper->Is(Type::Internal()));
 | 
| -        break;
 | 
| -      case IrOpcode::kFloat32Constant:
 | 
| -      case IrOpcode::kFloat64Constant:
 | 
| -      case IrOpcode::kNumberConstant:
 | 
| -        // Constants have no inputs.
 | 
| -        CHECK_EQ(0, input_count);
 | 
| -        // Type is a number.
 | 
| -        CHECK(bounds(node).upper->Is(Type::Number()));
 | 
| -        break;
 | 
| -      case IrOpcode::kHeapConstant:
 | 
| -        // Constants have no inputs.
 | 
| -        CHECK_EQ(0, input_count);
 | 
| -        // Type can be anything represented as a heap pointer.
 | 
| -        CHECK(bounds(node).upper->Is(Type::TaggedPtr()));
 | 
| -        break;
 | 
| -      case IrOpcode::kExternalConstant:
 | 
| -        // Constants have no inputs.
 | 
| -        CHECK_EQ(0, input_count);
 | 
| -        // Type is considered internal.
 | 
| -        CHECK(bounds(node).upper->Is(Type::Internal()));
 | 
| -        break;
 | 
| -      case IrOpcode::kProjection: {
 | 
| -        // Projection has an input that produces enough values.
 | 
| -        int index = OpParameter<int>(node->op());
 | 
| -        Node* input = NodeProperties::GetValueInput(node, 0);
 | 
| -        CHECK_GT(OperatorProperties::GetValueOutputCount(input->op()), index);
 | 
| -        // Type can be anything.
 | 
| -        // TODO(rossberg): Introduce tuple types for this.
 | 
| -        CHECK(bounds(node).upper->Is(Type::Any()));
 | 
| -        break;
 | 
| -      }
 | 
| -      case IrOpcode::kPhi: {
 | 
| -        // Phi input count matches parent control node.
 | 
| -        CHECK_EQ(1, control_count);
 | 
| -        Node* control = NodeProperties::GetControlInput(node, 0);
 | 
| -        CHECK_EQ(value_count,
 | 
| -                 OperatorProperties::GetControlInputCount(control->op()));
 | 
| -        // Type must be subsumed by all input types.
 | 
| -        // TODO(rossberg): for now at least, narrowing does not really hold.
 | 
| -        /*
 | 
| -        for (int i = 0; i < value_count; ++i) {
 | 
| -          // TODO(rossberg, jarin): Figure out what to do about lower bounds.
 | 
| -          // CHECK(bounds(node).lower->Is(bounds(Operand(node, i)).lower));
 | 
| -          CHECK(bounds(Operand(node, i)).upper->Is(bounds(node).upper));
 | 
| -        }
 | 
| -        */
 | 
| -        break;
 | 
| +  switch (node->opcode()) {
 | 
| +    case IrOpcode::kStart:
 | 
| +      // Start has no inputs.
 | 
| +      CHECK_EQ(0, input_count);
 | 
| +      // Type is a tuple.
 | 
| +      // TODO(rossberg): Multiple outputs are currently typed as Internal.
 | 
| +      CheckUpperIs(node, Type::Internal());
 | 
| +      break;
 | 
| +    case IrOpcode::kEnd:
 | 
| +      // End has no outputs.
 | 
| +      CHECK(!OperatorProperties::HasValueOutput(node->op()));
 | 
| +      CHECK(!OperatorProperties::HasEffectOutput(node->op()));
 | 
| +      CHECK(!OperatorProperties::HasControlOutput(node->op()));
 | 
| +      // Type is empty.
 | 
| +      CheckNotTyped(node);
 | 
| +      break;
 | 
| +    case IrOpcode::kDead:
 | 
| +      // Dead is never connected to the graph.
 | 
| +      UNREACHABLE();
 | 
| +    case IrOpcode::kBranch: {
 | 
| +      // Branch uses are IfTrue and IfFalse.
 | 
| +      Node::Uses uses = node->uses();
 | 
| +      int count_true = 0, count_false = 0;
 | 
| +      for (Node::Uses::iterator it = uses.begin(); it != uses.end(); ++it) {
 | 
| +        CHECK((*it)->opcode() == IrOpcode::kIfTrue ||
 | 
| +              (*it)->opcode() == IrOpcode::kIfFalse);
 | 
| +        if ((*it)->opcode() == IrOpcode::kIfTrue) ++count_true;
 | 
| +        if ((*it)->opcode() == IrOpcode::kIfFalse) ++count_false;
 | 
|        }
 | 
| -      case IrOpcode::kEffectPhi: {
 | 
| -        // EffectPhi input count matches parent control node.
 | 
| -        CHECK_EQ(1, control_count);
 | 
| -        Node* control = NodeProperties::GetControlInput(node, 0);
 | 
| -        CHECK_EQ(effect_count,
 | 
| -                 OperatorProperties::GetControlInputCount(control->op()));
 | 
| -        break;
 | 
| -      }
 | 
| -      case IrOpcode::kValueEffect:
 | 
| -        // TODO(rossberg): what are the constraints on these?
 | 
| -        break;
 | 
| -      case IrOpcode::kFinish: {
 | 
| -        // TODO(rossberg): what are the constraints on these?
 | 
| -        // Type must be subsumed by input type.
 | 
| -        CHECK(bounds(Operand(node)).lower->Is(bounds(node).lower));
 | 
| -        CHECK(bounds(Operand(node)).upper->Is(bounds(node).upper));
 | 
| -        break;
 | 
| +      CHECK(count_true == 1 && count_false == 1);
 | 
| +      // Type is empty.
 | 
| +      CheckNotTyped(node);
 | 
| +      break;
 | 
| +    }
 | 
| +    case IrOpcode::kIfTrue:
 | 
| +    case IrOpcode::kIfFalse:
 | 
| +      CHECK_EQ(IrOpcode::kBranch,
 | 
| +               NodeProperties::GetControlInput(node, 0)->opcode());
 | 
| +      // Type is empty.
 | 
| +      CheckNotTyped(node);
 | 
| +      break;
 | 
| +    case IrOpcode::kLoop:
 | 
| +    case IrOpcode::kMerge:
 | 
| +      CHECK_EQ(control_count, input_count);
 | 
| +      // Type is empty.
 | 
| +      CheckNotTyped(node);
 | 
| +      break;
 | 
| +    case IrOpcode::kReturn:
 | 
| +      // TODO(rossberg): check successor is End
 | 
| +      // Type is empty.
 | 
| +      CheckNotTyped(node);
 | 
| +      break;
 | 
| +    case IrOpcode::kThrow:
 | 
| +      // TODO(rossberg): what are the constraints on these?
 | 
| +      // Type is empty.
 | 
| +      CheckNotTyped(node);
 | 
| +      break;
 | 
| +
 | 
| +    // Common operators
 | 
| +    // ----------------
 | 
| +    case IrOpcode::kParameter: {
 | 
| +      // Parameters have the start node as inputs.
 | 
| +      CHECK_EQ(1, input_count);
 | 
| +      CHECK_EQ(IrOpcode::kStart,
 | 
| +               NodeProperties::GetValueInput(node, 0)->opcode());
 | 
| +      // Parameter has an input that produces enough values.
 | 
| +      int index = OpParameter<int>(node);
 | 
| +      Node* input = NodeProperties::GetValueInput(node, 0);
 | 
| +      // Currently, parameter indices start at -1 instead of 0.
 | 
| +      CHECK_GT(OperatorProperties::GetValueOutputCount(input->op()), index + 1);
 | 
| +      // Type can be anything.
 | 
| +      CheckUpperIs(node, Type::Any());
 | 
| +      break;
 | 
| +    }
 | 
| +    case IrOpcode::kInt32Constant:  // TODO(rossberg): rename Word32Constant?
 | 
| +      // Constants have no inputs.
 | 
| +      CHECK_EQ(0, input_count);
 | 
| +      // Type is a 32 bit integer, signed or unsigned.
 | 
| +      CheckUpperIs(node, Type::Integral32());
 | 
| +      break;
 | 
| +    case IrOpcode::kInt64Constant:
 | 
| +      // Constants have no inputs.
 | 
| +      CHECK_EQ(0, input_count);
 | 
| +      // Type is internal.
 | 
| +      // TODO(rossberg): Introduce proper Int64 type.
 | 
| +      CheckUpperIs(node, Type::Internal());
 | 
| +      break;
 | 
| +    case IrOpcode::kFloat32Constant:
 | 
| +    case IrOpcode::kFloat64Constant:
 | 
| +    case IrOpcode::kNumberConstant:
 | 
| +      // Constants have no inputs.
 | 
| +      CHECK_EQ(0, input_count);
 | 
| +      // Type is a number.
 | 
| +      CheckUpperIs(node, Type::Number());
 | 
| +      break;
 | 
| +    case IrOpcode::kHeapConstant:
 | 
| +      // Constants have no inputs.
 | 
| +      CHECK_EQ(0, input_count);
 | 
| +      // Type can be anything represented as a heap pointer.
 | 
| +      CheckUpperIs(node, Type::TaggedPtr());
 | 
| +      break;
 | 
| +    case IrOpcode::kExternalConstant:
 | 
| +      // Constants have no inputs.
 | 
| +      CHECK_EQ(0, input_count);
 | 
| +      // Type is considered internal.
 | 
| +      CheckUpperIs(node, Type::Internal());
 | 
| +      break;
 | 
| +    case IrOpcode::kProjection: {
 | 
| +      // Projection has an input that produces enough values.
 | 
| +      int index = OpParameter<int>(node->op());
 | 
| +      Node* input = NodeProperties::GetValueInput(node, 0);
 | 
| +      CHECK_GT(OperatorProperties::GetValueOutputCount(input->op()), index);
 | 
| +      // Type can be anything.
 | 
| +      // TODO(rossberg): Introduce tuple types for this.
 | 
| +      // TODO(titzer): Convince rossberg not to.
 | 
| +      CheckUpperIs(node, Type::Any());
 | 
| +      break;
 | 
| +    }
 | 
| +    case IrOpcode::kPhi: {
 | 
| +      // Phi input count matches parent control node.
 | 
| +      CHECK_EQ(0, effect_count);
 | 
| +      CHECK_EQ(1, control_count);
 | 
| +      Node* control = NodeProperties::GetControlInput(node, 0);
 | 
| +      CHECK_EQ(value_count,
 | 
| +               OperatorProperties::GetControlInputCount(control->op()));
 | 
| +      CHECK_EQ(input_count, 1 + value_count);
 | 
| +      // Type must be subsumed by all input types.
 | 
| +      // TODO(rossberg): for now at least, narrowing does not really hold.
 | 
| +      /*
 | 
| +      for (int i = 0; i < value_count; ++i) {
 | 
| +        // TODO(rossberg, jarin): Figure out what to do about lower bounds.
 | 
| +        // CHECK(bounds(node).lower->Is(bounds(ValueInput(node, i)).lower));
 | 
| +        CHECK(bounds(ValueInput(node, i)).upper->Is(bounds(node).upper));
 | 
|        }
 | 
| -      case IrOpcode::kFrameState:
 | 
| -        // TODO(jarin): what are the constraints on these?
 | 
| -        break;
 | 
| -      case IrOpcode::kStateValues:
 | 
| -        // TODO(jarin): what are the constraints on these?
 | 
| -        break;
 | 
| -      case IrOpcode::kCall:
 | 
| -        // TODO(rossberg): what are the constraints on these?
 | 
| -        break;
 | 
| -
 | 
| -      // JavaScript operators
 | 
| -      // --------------------
 | 
| -      case IrOpcode::kJSEqual:
 | 
| -      case IrOpcode::kJSNotEqual:
 | 
| -      case IrOpcode::kJSStrictEqual:
 | 
| -      case IrOpcode::kJSStrictNotEqual:
 | 
| -      case IrOpcode::kJSLessThan:
 | 
| -      case IrOpcode::kJSGreaterThan:
 | 
| -      case IrOpcode::kJSLessThanOrEqual:
 | 
| -      case IrOpcode::kJSGreaterThanOrEqual:
 | 
| -      case IrOpcode::kJSUnaryNot:
 | 
| -        // Type is Boolean.
 | 
| -        CHECK(bounds(node).upper->Is(Type::Boolean()));
 | 
| -        break;
 | 
| -
 | 
| -      case IrOpcode::kJSBitwiseOr:
 | 
| -      case IrOpcode::kJSBitwiseXor:
 | 
| -      case IrOpcode::kJSBitwiseAnd:
 | 
| -      case IrOpcode::kJSShiftLeft:
 | 
| -      case IrOpcode::kJSShiftRight:
 | 
| -      case IrOpcode::kJSShiftRightLogical:
 | 
| -        // Type is 32 bit integral.
 | 
| -        CHECK(bounds(node).upper->Is(Type::Integral32()));
 | 
| -        break;
 | 
| -      case IrOpcode::kJSAdd:
 | 
| -        // Type is Number or String.
 | 
| -        CHECK(bounds(node).upper->Is(Type::NumberOrString()));
 | 
| -        break;
 | 
| -      case IrOpcode::kJSSubtract:
 | 
| -      case IrOpcode::kJSMultiply:
 | 
| -      case IrOpcode::kJSDivide:
 | 
| -      case IrOpcode::kJSModulus:
 | 
| -        // Type is Number.
 | 
| -        CHECK(bounds(node).upper->Is(Type::Number()));
 | 
| -        break;
 | 
| -
 | 
| -      case IrOpcode::kJSToBoolean:
 | 
| -        // Type is Boolean.
 | 
| -        CHECK(bounds(node).upper->Is(Type::Boolean()));
 | 
| -        break;
 | 
| -      case IrOpcode::kJSToNumber:
 | 
| -        // Type is Number.
 | 
| -        CHECK(bounds(node).upper->Is(Type::Number()));
 | 
| -        break;
 | 
| -      case IrOpcode::kJSToString:
 | 
| -        // Type is String.
 | 
| -        CHECK(bounds(node).upper->Is(Type::String()));
 | 
| -        break;
 | 
| -      case IrOpcode::kJSToName:
 | 
| -        // Type is Name.
 | 
| -        CHECK(bounds(node).upper->Is(Type::Name()));
 | 
| -        break;
 | 
| -      case IrOpcode::kJSToObject:
 | 
| -        // Type is Receiver.
 | 
| -        CHECK(bounds(node).upper->Is(Type::Receiver()));
 | 
| -        break;
 | 
| -
 | 
| -      case IrOpcode::kJSCreate:
 | 
| -        // Type is Object.
 | 
| -        CHECK(bounds(node).upper->Is(Type::Object()));
 | 
| -        break;
 | 
| -      case IrOpcode::kJSLoadProperty:
 | 
| -      case IrOpcode::kJSLoadNamed:
 | 
| -        // Type can be anything.
 | 
| -        CHECK(bounds(node).upper->Is(Type::Any()));
 | 
| -        break;
 | 
| -      case IrOpcode::kJSStoreProperty:
 | 
| -      case IrOpcode::kJSStoreNamed:
 | 
| -        // Type is empty.
 | 
| -        CHECK(!NodeProperties::IsTyped(node));
 | 
| -        break;
 | 
| -      case IrOpcode::kJSDeleteProperty:
 | 
| -      case IrOpcode::kJSHasProperty:
 | 
| -      case IrOpcode::kJSInstanceOf:
 | 
| -        // Type is Boolean.
 | 
| -        CHECK(bounds(node).upper->Is(Type::Boolean()));
 | 
| -        break;
 | 
| -      case IrOpcode::kJSTypeOf:
 | 
| -        // Type is String.
 | 
| -        CHECK(bounds(node).upper->Is(Type::String()));
 | 
| -        break;
 | 
| -
 | 
| -      case IrOpcode::kJSLoadContext:
 | 
| -        // Type can be anything.
 | 
| -        CHECK(bounds(node).upper->Is(Type::Any()));
 | 
| -        break;
 | 
| -      case IrOpcode::kJSStoreContext:
 | 
| -        // Type is empty.
 | 
| -        CHECK(!NodeProperties::IsTyped(node));
 | 
| -        break;
 | 
| -      case IrOpcode::kJSCreateFunctionContext:
 | 
| -      case IrOpcode::kJSCreateCatchContext:
 | 
| -      case IrOpcode::kJSCreateWithContext:
 | 
| -      case IrOpcode::kJSCreateBlockContext:
 | 
| -      case IrOpcode::kJSCreateModuleContext:
 | 
| -      case IrOpcode::kJSCreateGlobalContext: {
 | 
| -        // Type is Context, and operand is Internal.
 | 
| -        Bounds outer = bounds(NodeProperties::GetContextInput(node));
 | 
| -        // TODO(rossberg): This should really be Is(Internal), but the typer
 | 
| -        // currently can't do backwards propagation.
 | 
| -        CHECK(outer.upper->Maybe(Type::Internal()));
 | 
| -        CHECK(bounds(node).upper->IsContext());
 | 
| -        break;
 | 
| +      */
 | 
| +      break;
 | 
| +    }
 | 
| +    case IrOpcode::kEffectPhi: {
 | 
| +      // EffectPhi input count matches parent control node.
 | 
| +      CHECK_EQ(0, value_count);
 | 
| +      CHECK_EQ(1, control_count);
 | 
| +      Node* control = NodeProperties::GetControlInput(node, 0);
 | 
| +      CHECK_EQ(effect_count,
 | 
| +               OperatorProperties::GetControlInputCount(control->op()));
 | 
| +      CHECK_EQ(input_count, 1 + effect_count);
 | 
| +      break;
 | 
| +    }
 | 
| +    case IrOpcode::kValueEffect:
 | 
| +      // TODO(rossberg): what are the constraints on these?
 | 
| +      break;
 | 
| +    case IrOpcode::kFinish: {
 | 
| +      // TODO(rossberg): what are the constraints on these?
 | 
| +      // Type must be subsumed by input type.
 | 
| +      if (typing == TYPED) {
 | 
| +        CHECK(bounds(ValueInput(node)).lower->Is(bounds(node).lower));
 | 
| +        CHECK(bounds(ValueInput(node)).upper->Is(bounds(node).upper));
 | 
|        }
 | 
| +      break;
 | 
| +    }
 | 
| +    case IrOpcode::kFrameState:
 | 
| +      // TODO(jarin): what are the constraints on these?
 | 
| +      break;
 | 
| +    case IrOpcode::kStateValues:
 | 
| +      // TODO(jarin): what are the constraints on these?
 | 
| +      break;
 | 
| +    case IrOpcode::kCall:
 | 
| +      // TODO(rossberg): what are the constraints on these?
 | 
| +      break;
 | 
| +
 | 
| +    // JavaScript operators
 | 
| +    // --------------------
 | 
| +    case IrOpcode::kJSEqual:
 | 
| +    case IrOpcode::kJSNotEqual:
 | 
| +    case IrOpcode::kJSStrictEqual:
 | 
| +    case IrOpcode::kJSStrictNotEqual:
 | 
| +    case IrOpcode::kJSLessThan:
 | 
| +    case IrOpcode::kJSGreaterThan:
 | 
| +    case IrOpcode::kJSLessThanOrEqual:
 | 
| +    case IrOpcode::kJSGreaterThanOrEqual:
 | 
| +    case IrOpcode::kJSUnaryNot:
 | 
| +      // Type is Boolean.
 | 
| +      CheckUpperIs(node, Type::Boolean());
 | 
| +      break;
 | 
| +
 | 
| +    case IrOpcode::kJSBitwiseOr:
 | 
| +    case IrOpcode::kJSBitwiseXor:
 | 
| +    case IrOpcode::kJSBitwiseAnd:
 | 
| +    case IrOpcode::kJSShiftLeft:
 | 
| +    case IrOpcode::kJSShiftRight:
 | 
| +    case IrOpcode::kJSShiftRightLogical:
 | 
| +      // Type is 32 bit integral.
 | 
| +      CheckUpperIs(node, Type::Integral32());
 | 
| +      break;
 | 
| +    case IrOpcode::kJSAdd:
 | 
| +      // Type is Number or String.
 | 
| +      CheckUpperIs(node, Type::NumberOrString());
 | 
| +      break;
 | 
| +    case IrOpcode::kJSSubtract:
 | 
| +    case IrOpcode::kJSMultiply:
 | 
| +    case IrOpcode::kJSDivide:
 | 
| +    case IrOpcode::kJSModulus:
 | 
| +      // Type is Number.
 | 
| +      CheckUpperIs(node, Type::Number());
 | 
| +      break;
 | 
| +
 | 
| +    case IrOpcode::kJSToBoolean:
 | 
| +      // Type is Boolean.
 | 
| +      CheckUpperIs(node, Type::Boolean());
 | 
| +      break;
 | 
| +    case IrOpcode::kJSToNumber:
 | 
| +      // Type is Number.
 | 
| +      CheckUpperIs(node, Type::Number());
 | 
| +      break;
 | 
| +    case IrOpcode::kJSToString:
 | 
| +      // Type is String.
 | 
| +      CheckUpperIs(node, Type::String());
 | 
| +      break;
 | 
| +    case IrOpcode::kJSToName:
 | 
| +      // Type is Name.
 | 
| +      CheckUpperIs(node, Type::Name());
 | 
| +      break;
 | 
| +    case IrOpcode::kJSToObject:
 | 
| +      // Type is Receiver.
 | 
| +      CheckUpperIs(node, Type::Receiver());
 | 
| +      break;
 | 
| +
 | 
| +    case IrOpcode::kJSCreate:
 | 
| +      // Type is Object.
 | 
| +      CheckUpperIs(node, Type::Object());
 | 
| +      break;
 | 
| +    case IrOpcode::kJSLoadProperty:
 | 
| +    case IrOpcode::kJSLoadNamed:
 | 
| +      // Type can be anything.
 | 
| +      CheckUpperIs(node, Type::Any());
 | 
| +      break;
 | 
| +    case IrOpcode::kJSStoreProperty:
 | 
| +    case IrOpcode::kJSStoreNamed:
 | 
| +      // Type is empty.
 | 
| +      CheckNotTyped(node);
 | 
| +      break;
 | 
| +    case IrOpcode::kJSDeleteProperty:
 | 
| +    case IrOpcode::kJSHasProperty:
 | 
| +    case IrOpcode::kJSInstanceOf:
 | 
| +      // Type is Boolean.
 | 
| +      CheckUpperIs(node, Type::Boolean());
 | 
| +      break;
 | 
| +    case IrOpcode::kJSTypeOf:
 | 
| +      // Type is String.
 | 
| +      CheckUpperIs(node, Type::String());
 | 
| +      break;
 | 
| +
 | 
| +    case IrOpcode::kJSLoadContext:
 | 
| +      // Type can be anything.
 | 
| +      CheckUpperIs(node, Type::Any());
 | 
| +      break;
 | 
| +    case IrOpcode::kJSStoreContext:
 | 
| +      // Type is empty.
 | 
| +      CheckNotTyped(node);
 | 
| +      break;
 | 
| +    case IrOpcode::kJSCreateFunctionContext:
 | 
| +    case IrOpcode::kJSCreateCatchContext:
 | 
| +    case IrOpcode::kJSCreateWithContext:
 | 
| +    case IrOpcode::kJSCreateBlockContext:
 | 
| +    case IrOpcode::kJSCreateModuleContext:
 | 
| +    case IrOpcode::kJSCreateGlobalContext: {
 | 
| +      // Type is Context, and operand is Internal.
 | 
| +      Node* context = NodeProperties::GetContextInput(node);
 | 
| +      // TODO(rossberg): This should really be Is(Internal), but the typer
 | 
| +      // currently can't do backwards propagation.
 | 
| +      CheckUpperMaybe(context, Type::Internal());
 | 
| +      if (typing == TYPED) CHECK(bounds(node).upper->IsContext());
 | 
| +      break;
 | 
| +    }
 | 
|  
 | 
| -      case IrOpcode::kJSCallConstruct:
 | 
| -        // Type is Receiver.
 | 
| -        CHECK(bounds(node).upper->Is(Type::Receiver()));
 | 
| -        break;
 | 
| -      case IrOpcode::kJSCallFunction:
 | 
| -      case IrOpcode::kJSCallRuntime:
 | 
| -      case IrOpcode::kJSYield:
 | 
| -      case IrOpcode::kJSDebugger:
 | 
| -        // Type can be anything.
 | 
| -        CHECK(bounds(node).upper->Is(Type::Any()));
 | 
| -        break;
 | 
| -
 | 
| -      // Simplified operators
 | 
| -      // -------------------------------
 | 
| -      case IrOpcode::kBooleanNot:
 | 
| -        // Boolean -> Boolean
 | 
| -        CHECK(bounds(Operand(node)).upper->Is(Type::Boolean()));
 | 
| -        CHECK(bounds(node).upper->Is(Type::Boolean()));
 | 
| -        break;
 | 
| -      case IrOpcode::kBooleanToNumber:
 | 
| -        // Boolean -> Number
 | 
| -        CHECK(bounds(Operand(node)).upper->Is(Type::Boolean()));
 | 
| -        CHECK(bounds(node).upper->Is(Type::Number()));
 | 
| -        break;
 | 
| -      case IrOpcode::kNumberEqual:
 | 
| -      case IrOpcode::kNumberLessThan:
 | 
| -      case IrOpcode::kNumberLessThanOrEqual:
 | 
| -        // (Number, Number) -> Boolean
 | 
| -        CHECK(bounds(Operand(node, 0)).upper->Is(Type::Number()));
 | 
| -        CHECK(bounds(Operand(node, 1)).upper->Is(Type::Number()));
 | 
| -        CHECK(bounds(node).upper->Is(Type::Boolean()));
 | 
| -        break;
 | 
| -      case IrOpcode::kNumberAdd:
 | 
| -      case IrOpcode::kNumberSubtract:
 | 
| -      case IrOpcode::kNumberMultiply:
 | 
| -      case IrOpcode::kNumberDivide:
 | 
| -      case IrOpcode::kNumberModulus:
 | 
| -        // (Number, Number) -> Number
 | 
| -        CHECK(bounds(Operand(node, 0)).upper->Is(Type::Number()));
 | 
| -        CHECK(bounds(Operand(node, 1)).upper->Is(Type::Number()));
 | 
| -        // TODO(rossberg): activate once we retype after opcode changes.
 | 
| -        // CHECK(bounds(node).upper->Is(Type::Number()));
 | 
| -        break;
 | 
| -      case IrOpcode::kNumberToInt32:
 | 
| -        // Number -> Signed32
 | 
| -        CHECK(bounds(Operand(node)).upper->Is(Type::Number()));
 | 
| -        CHECK(bounds(node).upper->Is(Type::Signed32()));
 | 
| -        break;
 | 
| -      case IrOpcode::kNumberToUint32:
 | 
| -        // Number -> Unsigned32
 | 
| -        CHECK(bounds(Operand(node)).upper->Is(Type::Number()));
 | 
| -        CHECK(bounds(node).upper->Is(Type::Unsigned32()));
 | 
| -        break;
 | 
| -      case IrOpcode::kStringEqual:
 | 
| -      case IrOpcode::kStringLessThan:
 | 
| -      case IrOpcode::kStringLessThanOrEqual:
 | 
| -        // (String, String) -> Boolean
 | 
| -        CHECK(bounds(Operand(node, 0)).upper->Is(Type::String()));
 | 
| -        CHECK(bounds(Operand(node, 1)).upper->Is(Type::String()));
 | 
| -        CHECK(bounds(node).upper->Is(Type::Boolean()));
 | 
| -        break;
 | 
| -      case IrOpcode::kStringAdd:
 | 
| -        // (String, String) -> String
 | 
| -        CHECK(bounds(Operand(node, 0)).upper->Is(Type::String()));
 | 
| -        CHECK(bounds(Operand(node, 1)).upper->Is(Type::String()));
 | 
| -        CHECK(bounds(node).upper->Is(Type::String()));
 | 
| -        break;
 | 
| -      case IrOpcode::kReferenceEqual: {
 | 
| -        // (Unique, Any) -> Boolean  and
 | 
| -        // (Any, Unique) -> Boolean
 | 
| -        CHECK(bounds(Operand(node, 0)).upper->Is(Type::Unique()) ||
 | 
| -              bounds(Operand(node, 1)).upper->Is(Type::Unique()));
 | 
| -        CHECK(bounds(node).upper->Is(Type::Boolean()));
 | 
| -        break;
 | 
| -      }
 | 
| -      case IrOpcode::kObjectIsSmi:
 | 
| -        CHECK(bounds(Operand(node)).upper->Is(Type::Any()));
 | 
| -        CHECK(bounds(node).upper->Is(Type::Boolean()));
 | 
| -        break;
 | 
| -      case IrOpcode::kObjectIsNonNegativeSmi:
 | 
| -        CHECK(bounds(Operand(node)).upper->Is(Type::Any()));
 | 
| -        CHECK(bounds(node).upper->Is(Type::Boolean()));
 | 
| -        break;
 | 
| -
 | 
| -      case IrOpcode::kChangeTaggedToInt32: {
 | 
| -        // Signed32 /\ Tagged -> Signed32 /\ UntaggedInt32
 | 
| -        // TODO(neis): Activate once ChangeRepresentation works in typer.
 | 
| -        // Type* from = Type::Intersect(Type::Signed32(), Type::Tagged());
 | 
| -        // Type* to = Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
 | 
| -        // CHECK(bounds(Operand(node)).upper->Is(from));
 | 
| -        // CHECK(bounds(node).upper->Is(to));
 | 
| -        break;
 | 
| +    case IrOpcode::kJSCallConstruct:
 | 
| +      // Type is Receiver.
 | 
| +      CheckUpperIs(node, Type::Receiver());
 | 
| +      break;
 | 
| +    case IrOpcode::kJSCallFunction:
 | 
| +    case IrOpcode::kJSCallRuntime:
 | 
| +    case IrOpcode::kJSYield:
 | 
| +    case IrOpcode::kJSDebugger:
 | 
| +      // Type can be anything.
 | 
| +      CheckUpperIs(node, Type::Any());
 | 
| +      break;
 | 
| +
 | 
| +    // Simplified operators
 | 
| +    // -------------------------------
 | 
| +    case IrOpcode::kBooleanNot:
 | 
| +      // Boolean -> Boolean
 | 
| +      CheckValueInputIs(node, 0, Type::Boolean());
 | 
| +      CheckUpperIs(node, Type::Boolean());
 | 
| +      break;
 | 
| +    case IrOpcode::kBooleanToNumber:
 | 
| +      // Boolean -> Number
 | 
| +      CheckValueInputIs(node, 0, Type::Boolean());
 | 
| +      CheckUpperIs(node, Type::Number());
 | 
| +      break;
 | 
| +    case IrOpcode::kNumberEqual:
 | 
| +    case IrOpcode::kNumberLessThan:
 | 
| +    case IrOpcode::kNumberLessThanOrEqual:
 | 
| +      // (Number, Number) -> Boolean
 | 
| +      CheckValueInputIs(node, 0, Type::Number());
 | 
| +      CheckValueInputIs(node, 1, Type::Number());
 | 
| +      CheckUpperIs(node, Type::Boolean());
 | 
| +      break;
 | 
| +    case IrOpcode::kNumberAdd:
 | 
| +    case IrOpcode::kNumberSubtract:
 | 
| +    case IrOpcode::kNumberMultiply:
 | 
| +    case IrOpcode::kNumberDivide:
 | 
| +    case IrOpcode::kNumberModulus:
 | 
| +      // (Number, Number) -> Number
 | 
| +      CheckValueInputIs(node, 0, Type::Number());
 | 
| +      CheckValueInputIs(node, 1, Type::Number());
 | 
| +      // TODO(rossberg): activate once we retype after opcode changes.
 | 
| +      // CheckUpperIs(node, Type::Number());
 | 
| +      break;
 | 
| +    case IrOpcode::kNumberToInt32:
 | 
| +      // Number -> Signed32
 | 
| +      CheckValueInputIs(node, 0, Type::Number());
 | 
| +      CheckUpperIs(node, Type::Signed32());
 | 
| +      break;
 | 
| +    case IrOpcode::kNumberToUint32:
 | 
| +      // Number -> Unsigned32
 | 
| +      CheckValueInputIs(node, 0, Type::Number());
 | 
| +      CheckUpperIs(node, Type::Unsigned32());
 | 
| +      break;
 | 
| +    case IrOpcode::kStringEqual:
 | 
| +    case IrOpcode::kStringLessThan:
 | 
| +    case IrOpcode::kStringLessThanOrEqual:
 | 
| +      // (String, String) -> Boolean
 | 
| +      CheckValueInputIs(node, 0, Type::String());
 | 
| +      CheckValueInputIs(node, 1, Type::String());
 | 
| +      CheckUpperIs(node, Type::Boolean());
 | 
| +      break;
 | 
| +    case IrOpcode::kStringAdd:
 | 
| +      // (String, String) -> String
 | 
| +      CheckValueInputIs(node, 0, Type::String());
 | 
| +      CheckValueInputIs(node, 1, Type::String());
 | 
| +      CheckUpperIs(node, Type::String());
 | 
| +      break;
 | 
| +    case IrOpcode::kReferenceEqual: {
 | 
| +      // (Unique, Any) -> Boolean  and
 | 
| +      // (Any, Unique) -> Boolean
 | 
| +      if (typing == TYPED) {
 | 
| +        CHECK(bounds(ValueInput(node, 0)).upper->Is(Type::Unique()) ||
 | 
| +              bounds(ValueInput(node, 1)).upper->Is(Type::Unique()));
 | 
|        }
 | 
| -      case IrOpcode::kChangeTaggedToUint32: {
 | 
| -        // Unsigned32 /\ Tagged -> Unsigned32 /\ UntaggedInt32
 | 
| -        // TODO(neis): Activate once ChangeRepresentation works in typer.
 | 
| -        // Type* from = Type::Intersect(Type::Unsigned32(), Type::Tagged());
 | 
| -        // Type* to =Type::Intersect(Type::Unsigned32(), Type::UntaggedInt32());
 | 
| -        // CHECK(bounds(Operand(node)).upper->Is(from));
 | 
| -        // CHECK(bounds(node).upper->Is(to));
 | 
| -        break;
 | 
| -      }
 | 
| -      case IrOpcode::kChangeTaggedToFloat64: {
 | 
| -        // Number /\ Tagged -> Number /\ UntaggedFloat64
 | 
| -        // TODO(neis): Activate once ChangeRepresentation works in typer.
 | 
| -        // Type* from = Type::Intersect(Type::Number(), Type::Tagged());
 | 
| -        // Type* to = Type::Intersect(Type::Number(), Type::UntaggedFloat64());
 | 
| -        // CHECK(bounds(Operand(node)).upper->Is(from));
 | 
| -        // CHECK(bounds(node).upper->Is(to));
 | 
| -        break;
 | 
| -      }
 | 
| -      case IrOpcode::kChangeInt32ToTagged: {
 | 
| -        // Signed32 /\ UntaggedInt32 -> Signed32 /\ Tagged
 | 
| -        // TODO(neis): Activate once ChangeRepresentation works in typer.
 | 
| -        // Type* from =Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
 | 
| -        // Type* to = Type::Intersect(Type::Signed32(), Type::Tagged());
 | 
| -        // CHECK(bounds(Operand(node)).upper->Is(from));
 | 
| -        // CHECK(bounds(node).upper->Is(to));
 | 
| -        break;
 | 
| -      }
 | 
| -      case IrOpcode::kChangeUint32ToTagged: {
 | 
| -        // Unsigned32 /\ UntaggedInt32 -> Unsigned32 /\ Tagged
 | 
| -        // TODO(neis): Activate once ChangeRepresentation works in typer.
 | 
| -        // Type* from=Type::Intersect(Type::Unsigned32(),Type::UntaggedInt32());
 | 
| -        // Type* to = Type::Intersect(Type::Unsigned32(), Type::Tagged());
 | 
| -        // CHECK(bounds(Operand(node)).upper->Is(from));
 | 
| -        // CHECK(bounds(node).upper->Is(to));
 | 
| -        break;
 | 
| -      }
 | 
| -      case IrOpcode::kChangeFloat64ToTagged: {
 | 
| -        // Number /\ UntaggedFloat64 -> Number /\ Tagged
 | 
| -        // TODO(neis): Activate once ChangeRepresentation works in typer.
 | 
| -        // Type* from =Type::Intersect(Type::Number(), Type::UntaggedFloat64());
 | 
| -        // Type* to = Type::Intersect(Type::Number(), Type::Tagged());
 | 
| -        // CHECK(bounds(Operand(node)).upper->Is(from));
 | 
| -        // CHECK(bounds(node).upper->Is(to));
 | 
| -        break;
 | 
| -      }
 | 
| -      case IrOpcode::kChangeBoolToBit: {
 | 
| -        // Boolean /\ TaggedPtr -> Boolean /\ UntaggedInt1
 | 
| -        // TODO(neis): Activate once ChangeRepresentation works in typer.
 | 
| -        // Type* from = Type::Intersect(Type::Boolean(), Type::TaggedPtr());
 | 
| -        // Type* to = Type::Intersect(Type::Boolean(), Type::UntaggedInt1());
 | 
| -        // CHECK(bounds(Operand(node)).upper->Is(from));
 | 
| -        // CHECK(bounds(node).upper->Is(to));
 | 
| -        break;
 | 
| -      }
 | 
| -      case IrOpcode::kChangeBitToBool: {
 | 
| -        // Boolean /\ UntaggedInt1 -> Boolean /\ TaggedPtr
 | 
| -        // TODO(neis): Activate once ChangeRepresentation works in typer.
 | 
| -        // Type* from = Type::Intersect(Type::Boolean(), Type::UntaggedInt1());
 | 
| -        // Type* to = Type::Intersect(Type::Boolean(), Type::TaggedPtr());
 | 
| -        // CHECK(bounds(Operand(node)).upper->Is(from));
 | 
| -        // CHECK(bounds(node).upper->Is(to));
 | 
| -        break;
 | 
| -      }
 | 
| -
 | 
| -      case IrOpcode::kLoadField:
 | 
| -        // Object -> fieldtype
 | 
| -        // TODO(rossberg): activate once machine ops are typed.
 | 
| -        // CHECK(bounds(Operand(node)).upper->Is(Type::Object()));
 | 
| -        // CHECK(bounds(node).upper->Is(Field(node).type));
 | 
| -        break;
 | 
| -      case IrOpcode::kLoadElement:
 | 
| -        // Object -> elementtype
 | 
| -        // TODO(rossberg): activate once machine ops are typed.
 | 
| -        // CHECK(bounds(Operand(node)).upper->Is(Type::Object()));
 | 
| -        // CHECK(bounds(node).upper->Is(Element(node).type));
 | 
| -        break;
 | 
| -      case IrOpcode::kStoreField:
 | 
| -        // (Object, fieldtype) -> _|_
 | 
| -        // TODO(rossberg): activate once machine ops are typed.
 | 
| -        // CHECK(bounds(Operand(node, 0)).upper->Is(Type::Object()));
 | 
| -        // CHECK(bounds(Operand(node, 1)).upper->Is(Field(node).type));
 | 
| -        CHECK(!NodeProperties::IsTyped(node));
 | 
| -        break;
 | 
| -      case IrOpcode::kStoreElement:
 | 
| -        // (Object, elementtype) -> _|_
 | 
| -        // TODO(rossberg): activate once machine ops are typed.
 | 
| -        // CHECK(bounds(Operand(node, 0)).upper->Is(Type::Object()));
 | 
| -        // CHECK(bounds(Operand(node, 1)).upper->Is(Element(node).type));
 | 
| -        CHECK(!NodeProperties::IsTyped(node));
 | 
| -        break;
 | 
| -
 | 
| -      // Machine operators
 | 
| -      // -----------------------
 | 
| -      case IrOpcode::kLoad:
 | 
| -      case IrOpcode::kStore:
 | 
| -      case IrOpcode::kWord32And:
 | 
| -      case IrOpcode::kWord32Or:
 | 
| -      case IrOpcode::kWord32Xor:
 | 
| -      case IrOpcode::kWord32Shl:
 | 
| -      case IrOpcode::kWord32Shr:
 | 
| -      case IrOpcode::kWord32Sar:
 | 
| -      case IrOpcode::kWord32Ror:
 | 
| -      case IrOpcode::kWord32Equal:
 | 
| -      case IrOpcode::kWord64And:
 | 
| -      case IrOpcode::kWord64Or:
 | 
| -      case IrOpcode::kWord64Xor:
 | 
| -      case IrOpcode::kWord64Shl:
 | 
| -      case IrOpcode::kWord64Shr:
 | 
| -      case IrOpcode::kWord64Sar:
 | 
| -      case IrOpcode::kWord64Ror:
 | 
| -      case IrOpcode::kWord64Equal:
 | 
| -      case IrOpcode::kInt32Add:
 | 
| -      case IrOpcode::kInt32AddWithOverflow:
 | 
| -      case IrOpcode::kInt32Sub:
 | 
| -      case IrOpcode::kInt32SubWithOverflow:
 | 
| -      case IrOpcode::kInt32Mul:
 | 
| -      case IrOpcode::kInt32MulHigh:
 | 
| -      case IrOpcode::kInt32Div:
 | 
| -      case IrOpcode::kInt32Mod:
 | 
| -      case IrOpcode::kInt32LessThan:
 | 
| -      case IrOpcode::kInt32LessThanOrEqual:
 | 
| -      case IrOpcode::kUint32Div:
 | 
| -      case IrOpcode::kUint32Mod:
 | 
| -      case IrOpcode::kUint32LessThan:
 | 
| -      case IrOpcode::kUint32LessThanOrEqual:
 | 
| -      case IrOpcode::kInt64Add:
 | 
| -      case IrOpcode::kInt64Sub:
 | 
| -      case IrOpcode::kInt64Mul:
 | 
| -      case IrOpcode::kInt64Div:
 | 
| -      case IrOpcode::kInt64Mod:
 | 
| -      case IrOpcode::kInt64LessThan:
 | 
| -      case IrOpcode::kInt64LessThanOrEqual:
 | 
| -      case IrOpcode::kUint64Div:
 | 
| -      case IrOpcode::kUint64Mod:
 | 
| -      case IrOpcode::kUint64LessThan:
 | 
| -      case IrOpcode::kFloat64Add:
 | 
| -      case IrOpcode::kFloat64Sub:
 | 
| -      case IrOpcode::kFloat64Mul:
 | 
| -      case IrOpcode::kFloat64Div:
 | 
| -      case IrOpcode::kFloat64Mod:
 | 
| -      case IrOpcode::kFloat64Sqrt:
 | 
| -      case IrOpcode::kFloat64Equal:
 | 
| -      case IrOpcode::kFloat64LessThan:
 | 
| -      case IrOpcode::kFloat64LessThanOrEqual:
 | 
| -      case IrOpcode::kTruncateInt64ToInt32:
 | 
| -      case IrOpcode::kTruncateFloat64ToFloat32:
 | 
| -      case IrOpcode::kTruncateFloat64ToInt32:
 | 
| -      case IrOpcode::kChangeInt32ToInt64:
 | 
| -      case IrOpcode::kChangeUint32ToUint64:
 | 
| -      case IrOpcode::kChangeInt32ToFloat64:
 | 
| -      case IrOpcode::kChangeUint32ToFloat64:
 | 
| -      case IrOpcode::kChangeFloat32ToFloat64:
 | 
| -      case IrOpcode::kChangeFloat64ToInt32:
 | 
| -      case IrOpcode::kChangeFloat64ToUint32:
 | 
| -      case IrOpcode::kLoadStackPointer:
 | 
| -        // TODO(rossberg): Check.
 | 
| -        break;
 | 
| +      CheckUpperIs(node, Type::Boolean());
 | 
| +      break;
 | 
| +    }
 | 
| +    case IrOpcode::kObjectIsSmi:
 | 
| +      CheckValueInputIs(node, 0, Type::Any());
 | 
| +      CheckUpperIs(node, Type::Boolean());
 | 
| +      break;
 | 
| +    case IrOpcode::kObjectIsNonNegativeSmi:
 | 
| +      CheckValueInputIs(node, 0, Type::Any());
 | 
| +      CheckUpperIs(node, Type::Boolean());
 | 
| +      break;
 | 
| +
 | 
| +    case IrOpcode::kChangeTaggedToInt32: {
 | 
| +      // Signed32 /\ Tagged -> Signed32 /\ UntaggedInt32
 | 
| +      // TODO(neis): Activate once ChangeRepresentation works in typer.
 | 
| +      // Type* from = Type::Intersect(Type::Signed32(), Type::Tagged());
 | 
| +      // Type* to = Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
 | 
| +      // CheckValueInputIs(node, 0, from));
 | 
| +      // CheckUpperIs(node, to));
 | 
| +      break;
 | 
|      }
 | 
| +    case IrOpcode::kChangeTaggedToUint32: {
 | 
| +      // Unsigned32 /\ Tagged -> Unsigned32 /\ UntaggedInt32
 | 
| +      // TODO(neis): Activate once ChangeRepresentation works in typer.
 | 
| +      // Type* from = Type::Intersect(Type::Unsigned32(), Type::Tagged());
 | 
| +      // Type* to =Type::Intersect(Type::Unsigned32(), Type::UntaggedInt32());
 | 
| +      // CheckValueInputIs(node, 0, from));
 | 
| +      // CheckUpperIs(node, to));
 | 
| +      break;
 | 
| +    }
 | 
| +    case IrOpcode::kChangeTaggedToFloat64: {
 | 
| +      // Number /\ Tagged -> Number /\ UntaggedFloat64
 | 
| +      // TODO(neis): Activate once ChangeRepresentation works in typer.
 | 
| +      // Type* from = Type::Intersect(Type::Number(), Type::Tagged());
 | 
| +      // Type* to = Type::Intersect(Type::Number(), Type::UntaggedFloat64());
 | 
| +      // CheckValueInputIs(node, 0, from));
 | 
| +      // CheckUpperIs(node, to));
 | 
| +      break;
 | 
| +    }
 | 
| +    case IrOpcode::kChangeInt32ToTagged: {
 | 
| +      // Signed32 /\ UntaggedInt32 -> Signed32 /\ Tagged
 | 
| +      // TODO(neis): Activate once ChangeRepresentation works in typer.
 | 
| +      // Type* from =Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
 | 
| +      // Type* to = Type::Intersect(Type::Signed32(), Type::Tagged());
 | 
| +      // CheckValueInputIs(node, 0, from));
 | 
| +      // CheckUpperIs(node, to));
 | 
| +      break;
 | 
| +    }
 | 
| +    case IrOpcode::kChangeUint32ToTagged: {
 | 
| +      // Unsigned32 /\ UntaggedInt32 -> Unsigned32 /\ Tagged
 | 
| +      // TODO(neis): Activate once ChangeRepresentation works in typer.
 | 
| +      // Type* from=Type::Intersect(Type::Unsigned32(),Type::UntaggedInt32());
 | 
| +      // Type* to = Type::Intersect(Type::Unsigned32(), Type::Tagged());
 | 
| +      // CheckValueInputIs(node, 0, from));
 | 
| +      // CheckUpperIs(node, to));
 | 
| +      break;
 | 
| +    }
 | 
| +    case IrOpcode::kChangeFloat64ToTagged: {
 | 
| +      // Number /\ UntaggedFloat64 -> Number /\ Tagged
 | 
| +      // TODO(neis): Activate once ChangeRepresentation works in typer.
 | 
| +      // Type* from =Type::Intersect(Type::Number(), Type::UntaggedFloat64());
 | 
| +      // Type* to = Type::Intersect(Type::Number(), Type::Tagged());
 | 
| +      // CheckValueInputIs(node, 0, from));
 | 
| +      // CheckUpperIs(node, to));
 | 
| +      break;
 | 
| +    }
 | 
| +    case IrOpcode::kChangeBoolToBit: {
 | 
| +      // Boolean /\ TaggedPtr -> Boolean /\ UntaggedInt1
 | 
| +      // TODO(neis): Activate once ChangeRepresentation works in typer.
 | 
| +      // Type* from = Type::Intersect(Type::Boolean(), Type::TaggedPtr());
 | 
| +      // Type* to = Type::Intersect(Type::Boolean(), Type::UntaggedInt1());
 | 
| +      // CheckValueInputIs(node, 0, from));
 | 
| +      // CheckUpperIs(node, to));
 | 
| +      break;
 | 
| +    }
 | 
| +    case IrOpcode::kChangeBitToBool: {
 | 
| +      // Boolean /\ UntaggedInt1 -> Boolean /\ TaggedPtr
 | 
| +      // TODO(neis): Activate once ChangeRepresentation works in typer.
 | 
| +      // Type* from = Type::Intersect(Type::Boolean(), Type::UntaggedInt1());
 | 
| +      // Type* to = Type::Intersect(Type::Boolean(), Type::TaggedPtr());
 | 
| +      // CheckValueInputIs(node, 0, from));
 | 
| +      // CheckUpperIs(node, to));
 | 
| +      break;
 | 
| +    }
 | 
| +
 | 
| +    case IrOpcode::kLoadField:
 | 
| +      // Object -> fieldtype
 | 
| +      // TODO(rossberg): activate once machine ops are typed.
 | 
| +      // CheckValueInputIs(node, 0, Type::Object());
 | 
| +      // CheckUpperIs(node, Field(node).type));
 | 
| +      break;
 | 
| +    case IrOpcode::kLoadElement:
 | 
| +      // Object -> elementtype
 | 
| +      // TODO(rossberg): activate once machine ops are typed.
 | 
| +      // CheckValueInputIs(node, 0, Type::Object());
 | 
| +      // CheckUpperIs(node, Element(node).type));
 | 
| +      break;
 | 
| +    case IrOpcode::kStoreField:
 | 
| +      // (Object, fieldtype) -> _|_
 | 
| +      // TODO(rossberg): activate once machine ops are typed.
 | 
| +      // CheckValueInputIs(node, 0, Type::Object());
 | 
| +      // CheckValueInputIs(node, 1, Field(node).type));
 | 
| +      CheckNotTyped(node);
 | 
| +      break;
 | 
| +    case IrOpcode::kStoreElement:
 | 
| +      // (Object, elementtype) -> _|_
 | 
| +      // TODO(rossberg): activate once machine ops are typed.
 | 
| +      // CheckValueInputIs(node, 0, Type::Object());
 | 
| +      // CheckValueInputIs(node, 1, Element(node).type));
 | 
| +      CheckNotTyped(node);
 | 
| +      break;
 | 
| +
 | 
| +    // Machine operators
 | 
| +    // -----------------------
 | 
| +    case IrOpcode::kLoad:
 | 
| +    case IrOpcode::kStore:
 | 
| +    case IrOpcode::kWord32And:
 | 
| +    case IrOpcode::kWord32Or:
 | 
| +    case IrOpcode::kWord32Xor:
 | 
| +    case IrOpcode::kWord32Shl:
 | 
| +    case IrOpcode::kWord32Shr:
 | 
| +    case IrOpcode::kWord32Sar:
 | 
| +    case IrOpcode::kWord32Ror:
 | 
| +    case IrOpcode::kWord32Equal:
 | 
| +    case IrOpcode::kWord64And:
 | 
| +    case IrOpcode::kWord64Or:
 | 
| +    case IrOpcode::kWord64Xor:
 | 
| +    case IrOpcode::kWord64Shl:
 | 
| +    case IrOpcode::kWord64Shr:
 | 
| +    case IrOpcode::kWord64Sar:
 | 
| +    case IrOpcode::kWord64Ror:
 | 
| +    case IrOpcode::kWord64Equal:
 | 
| +    case IrOpcode::kInt32Add:
 | 
| +    case IrOpcode::kInt32AddWithOverflow:
 | 
| +    case IrOpcode::kInt32Sub:
 | 
| +    case IrOpcode::kInt32SubWithOverflow:
 | 
| +    case IrOpcode::kInt32Mul:
 | 
| +    case IrOpcode::kInt32MulHigh:
 | 
| +    case IrOpcode::kInt32Div:
 | 
| +    case IrOpcode::kInt32Mod:
 | 
| +    case IrOpcode::kInt32LessThan:
 | 
| +    case IrOpcode::kInt32LessThanOrEqual:
 | 
| +    case IrOpcode::kUint32Div:
 | 
| +    case IrOpcode::kUint32Mod:
 | 
| +    case IrOpcode::kUint32LessThan:
 | 
| +    case IrOpcode::kUint32LessThanOrEqual:
 | 
| +    case IrOpcode::kInt64Add:
 | 
| +    case IrOpcode::kInt64Sub:
 | 
| +    case IrOpcode::kInt64Mul:
 | 
| +    case IrOpcode::kInt64Div:
 | 
| +    case IrOpcode::kInt64Mod:
 | 
| +    case IrOpcode::kInt64LessThan:
 | 
| +    case IrOpcode::kInt64LessThanOrEqual:
 | 
| +    case IrOpcode::kUint64Div:
 | 
| +    case IrOpcode::kUint64Mod:
 | 
| +    case IrOpcode::kUint64LessThan:
 | 
| +    case IrOpcode::kFloat64Add:
 | 
| +    case IrOpcode::kFloat64Sub:
 | 
| +    case IrOpcode::kFloat64Mul:
 | 
| +    case IrOpcode::kFloat64Div:
 | 
| +    case IrOpcode::kFloat64Mod:
 | 
| +    case IrOpcode::kFloat64Sqrt:
 | 
| +    case IrOpcode::kFloat64Equal:
 | 
| +    case IrOpcode::kFloat64LessThan:
 | 
| +    case IrOpcode::kFloat64LessThanOrEqual:
 | 
| +    case IrOpcode::kTruncateInt64ToInt32:
 | 
| +    case IrOpcode::kTruncateFloat64ToFloat32:
 | 
| +    case IrOpcode::kTruncateFloat64ToInt32:
 | 
| +    case IrOpcode::kChangeInt32ToInt64:
 | 
| +    case IrOpcode::kChangeUint32ToUint64:
 | 
| +    case IrOpcode::kChangeInt32ToFloat64:
 | 
| +    case IrOpcode::kChangeUint32ToFloat64:
 | 
| +    case IrOpcode::kChangeFloat32ToFloat64:
 | 
| +    case IrOpcode::kChangeFloat64ToInt32:
 | 
| +    case IrOpcode::kChangeFloat64ToUint32:
 | 
| +    case IrOpcode::kLoadStackPointer:
 | 
| +      // TODO(rossberg): Check.
 | 
| +      break;
 | 
|    }
 | 
|  
 | 
|    return GenericGraphVisit::CONTINUE;
 | 
| 
 |