// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/compiler/typer.h"

#include "src/base/flags.h"
#include "src/bootstrapper.h"
#include "src/compilation-dependencies.h"
#include "src/compiler/common-operator.h"
#include "src/compiler/graph-reducer.h"
#include "src/compiler/js-operator.h"
#include "src/compiler/node-properties.h"
#include "src/compiler/node.h"
#include "src/compiler/operation-typer.h"
#include "src/compiler/simplified-operator.h"
#include "src/objects-inl.h"
#include "src/type-cache.h"

namespace v8 {
namespace internal {
namespace compiler {

class Typer::Decorator final : public GraphDecorator {
 public:
  explicit Decorator(Typer* typer) : typer_(typer) {}
  void Decorate(Node* node) final;

 private:
  Typer* const typer_;
};

Typer::Typer(Isolate* isolate, Graph* graph, Flags flags,
             CompilationDependencies* dependencies, FunctionType* function_type)
    : isolate_(isolate),
      graph_(graph),
      flags_(flags),
      dependencies_(dependencies),
      function_type_(function_type),
      decorator_(nullptr),
      cache_(TypeCache::Get()),
      operation_typer_(isolate, zone()) {
  Zone* zone = this->zone();
  Factory* const factory = isolate->factory();

  Type* infinity = Type::Constant(factory->infinity_value(), zone);
  Type* minus_infinity = Type::Constant(factory->minus_infinity_value(), zone);
  // Unfortunately, the infinities created in other places might be different
  // ones (eg the result of NewNumber in TypeNumberConstant).
  Type* truncating_to_zero =
      Type::Union(Type::Union(infinity, minus_infinity, zone),
                  Type::MinusZeroOrNaN(), zone);
  DCHECK(!truncating_to_zero->Maybe(Type::Integral32()));

  singleton_false_ = Type::Constant(factory->false_value(), zone);
  singleton_true_ = Type::Constant(factory->true_value(), zone);
  singleton_the_hole_ = Type::Constant(factory->the_hole_value(), zone);
  signed32ish_ = Type::Union(Type::Signed32(), truncating_to_zero, zone);
  unsigned32ish_ = Type::Union(Type::Unsigned32(), truncating_to_zero, zone);
  falsish_ = Type::Union(
      Type::Undetectable(),
      Type::Union(Type::Union(singleton_false_, cache_.kZeroish, zone),
                  singleton_the_hole_, zone),
      zone);
  truish_ = Type::Union(
      singleton_true_,
      Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone);

  decorator_ = new (zone) Decorator(this);
  graph_->AddDecorator(decorator_);
}


Typer::~Typer() {
  graph_->RemoveDecorator(decorator_);
}


class Typer::Visitor : public Reducer {
 public:
  explicit Visitor(Typer* typer)
      : typer_(typer), weakened_nodes_(typer->zone()) {}

  Reduction Reduce(Node* node) override {
    if (node->op()->ValueOutputCount() == 0) return NoChange();
    switch (node->opcode()) {
#define DECLARE_CASE(x) \
  case IrOpcode::k##x:  \
    return UpdateType(node, TypeBinaryOp(node, x##Typer));
      JS_SIMPLE_BINOP_LIST(DECLARE_CASE)
#undef DECLARE_CASE

#define DECLARE_CASE(x) \
  case IrOpcode::k##x:  \
    return UpdateType(node, Type##x(node));
      DECLARE_CASE(Start)
      DECLARE_CASE(IfException)
      // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
      COMMON_OP_LIST(DECLARE_CASE)
      SIMPLIFIED_OP_LIST(DECLARE_CASE)
      MACHINE_OP_LIST(DECLARE_CASE)
      MACHINE_SIMD_OP_LIST(DECLARE_CASE)
      JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
      JS_OBJECT_OP_LIST(DECLARE_CASE)
      JS_CONTEXT_OP_LIST(DECLARE_CASE)
      JS_OTHER_OP_LIST(DECLARE_CASE)
#undef DECLARE_CASE

#define DECLARE_CASE(x) case IrOpcode::k##x:
      DECLARE_CASE(Loop)
      DECLARE_CASE(Branch)
      DECLARE_CASE(IfTrue)
      DECLARE_CASE(IfFalse)
      DECLARE_CASE(IfSuccess)
      DECLARE_CASE(Switch)
      DECLARE_CASE(IfValue)
      DECLARE_CASE(IfDefault)
      DECLARE_CASE(Merge)
      DECLARE_CASE(Deoptimize)
      DECLARE_CASE(DeoptimizeIf)
      DECLARE_CASE(DeoptimizeUnless)
      DECLARE_CASE(Return)
      DECLARE_CASE(TailCall)
      DECLARE_CASE(Terminate)
      DECLARE_CASE(OsrNormalEntry)
      DECLARE_CASE(OsrLoopEntry)
      DECLARE_CASE(Throw)
      DECLARE_CASE(End)
#undef DECLARE_CASE
      break;
    }
    return NoChange();
  }

  Type* TypeNode(Node* node) {
    switch (node->opcode()) {
#define DECLARE_CASE(x) \
      case IrOpcode::k##x: return TypeBinaryOp(node, x##Typer);
      JS_SIMPLE_BINOP_LIST(DECLARE_CASE)
#undef DECLARE_CASE

#define DECLARE_CASE(x) case IrOpcode::k##x: return Type##x(node);
      DECLARE_CASE(Start)
      DECLARE_CASE(IfException)
      // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
      COMMON_OP_LIST(DECLARE_CASE)
      SIMPLIFIED_OP_LIST(DECLARE_CASE)
      MACHINE_OP_LIST(DECLARE_CASE)
      MACHINE_SIMD_OP_LIST(DECLARE_CASE)
      JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
      JS_OBJECT_OP_LIST(DECLARE_CASE)
      JS_CONTEXT_OP_LIST(DECLARE_CASE)
      JS_OTHER_OP_LIST(DECLARE_CASE)
#undef DECLARE_CASE

#define DECLARE_CASE(x) case IrOpcode::k##x:
      DECLARE_CASE(Loop)
      DECLARE_CASE(Branch)
      DECLARE_CASE(IfTrue)
      DECLARE_CASE(IfFalse)
      DECLARE_CASE(IfSuccess)
      DECLARE_CASE(Switch)
      DECLARE_CASE(IfValue)
      DECLARE_CASE(IfDefault)
      DECLARE_CASE(Merge)
      DECLARE_CASE(Deoptimize)
      DECLARE_CASE(DeoptimizeIf)
      DECLARE_CASE(DeoptimizeUnless)
      DECLARE_CASE(Return)
      DECLARE_CASE(TailCall)
      DECLARE_CASE(Terminate)
      DECLARE_CASE(OsrNormalEntry)
      DECLARE_CASE(OsrLoopEntry)
      DECLARE_CASE(Throw)
      DECLARE_CASE(End)
#undef DECLARE_CASE
      break;
    }
    UNREACHABLE();
    return nullptr;
  }

  Type* TypeConstant(Handle<Object> value);

 private:
  Typer* typer_;
  ZoneSet<NodeId> weakened_nodes_;

#define DECLARE_METHOD(x) inline Type* Type##x(Node* node);
  DECLARE_METHOD(Start)
  DECLARE_METHOD(IfException)
  VALUE_OP_LIST(DECLARE_METHOD)
#undef DECLARE_METHOD

  Type* TypeOrNone(Node* node) {
    return NodeProperties::IsTyped(node) ? NodeProperties::GetType(node)
                                         : Type::None();
  }

  Type* Operand(Node* node, int i) {
    Node* operand_node = NodeProperties::GetValueInput(node, i);
    return TypeOrNone(operand_node);
  }

  Type* WrapContextTypeForInput(Node* node);
  Type* Weaken(Node* node, Type* current_type, Type* previous_type);

  Zone* zone() { return typer_->zone(); }
  Isolate* isolate() { return typer_->isolate(); }
  Graph* graph() { return typer_->graph(); }
  Typer::Flags flags() const { return typer_->flags(); }
  CompilationDependencies* dependencies() const {
    return typer_->dependencies();
  }

  void SetWeakened(NodeId node_id) { weakened_nodes_.insert(node_id); }
  bool IsWeakened(NodeId node_id) {
    return weakened_nodes_.find(node_id) != weakened_nodes_.end();
  }

  typedef Type* (*UnaryTyperFun)(Type*, Typer* t);
  typedef Type* (*BinaryTyperFun)(Type*, Type*, Typer* t);

  Type* TypeUnaryOp(Node* node, UnaryTyperFun);
  Type* TypeBinaryOp(Node* node, BinaryTyperFun);

  enum ComparisonOutcomeFlags {
    kComparisonTrue = 1,
    kComparisonFalse = 2,
    kComparisonUndefined = 4
  };
  typedef base::Flags<ComparisonOutcomeFlags> ComparisonOutcome;

  static ComparisonOutcome Invert(ComparisonOutcome, Typer*);
  static Type* Invert(Type*, Typer*);
  static Type* FalsifyUndefined(ComparisonOutcome, Typer*);

  static Type* ToPrimitive(Type*, Typer*);
  static Type* ToBoolean(Type*, Typer*);
  static Type* ToInteger(Type*, Typer*);
  static Type* ToLength(Type*, Typer*);
  static Type* ToName(Type*, Typer*);
  static Type* ToNumber(Type*, Typer*);
  static Type* ToObject(Type*, Typer*);
  static Type* ToString(Type*, Typer*);
  static Type* NumberAbs(Type*, Typer*);
  static Type* NumberCeil(Type*, Typer*);
  static Type* NumberFloor(Type*, Typer*);
  static Type* NumberRound(Type*, Typer*);
  static Type* NumberTrunc(Type*, Typer*);
  static Type* NumberToInt32(Type*, Typer*);
  static Type* NumberToUint32(Type*, Typer*);

  static Type* ObjectIsCallable(Type*, Typer*);
  static Type* ObjectIsNumber(Type*, Typer*);
  static Type* ObjectIsReceiver(Type*, Typer*);
  static Type* ObjectIsSmi(Type*, Typer*);
  static Type* ObjectIsString(Type*, Typer*);
  static Type* ObjectIsUndetectable(Type*, Typer*);

  static ComparisonOutcome JSCompareTyper(Type*, Type*, Typer*);

#define DECLARE_METHOD(x) static Type* x##Typer(Type*, Type*, Typer*);
  JS_SIMPLE_BINOP_LIST(DECLARE_METHOD)
#undef DECLARE_METHOD

  static Type* JSTypeOfTyper(Type*, Typer*);
  static Type* JSLoadPropertyTyper(Type*, Type*, Typer*);
  static Type* JSCallFunctionTyper(Type*, Typer*);

  static Type* ReferenceEqualTyper(Type*, Type*, Typer*);
  static Type* StringFromCharCodeTyper(Type*, Typer*);

  Reduction UpdateType(Node* node, Type* current) {
    if (NodeProperties::IsTyped(node)) {
      // Widen the type of a previously typed node.
      Type* previous = NodeProperties::GetType(node);
      if (node->opcode() == IrOpcode::kPhi) {
        // Speed up termination in the presence of range types:
        current = Weaken(node, current, previous);
      }

      CHECK(previous->Is(current));

      NodeProperties::SetType(node, current);
      if (!current->Is(previous)) {
        // If something changed, revisit all uses.
        return Changed(node);
      }
      return NoChange();
    } else {
      // No previous type, simply update the type.
      NodeProperties::SetType(node, current);
      return Changed(node);
    }
  }
};


void Typer::Run() { Run(NodeVector(zone())); }


void Typer::Run(const NodeVector& roots) {
  Visitor visitor(this);
  GraphReducer graph_reducer(zone(), graph());
  graph_reducer.AddReducer(&visitor);
  for (Node* const root : roots) graph_reducer.ReduceNode(root);
  graph_reducer.ReduceGraph();
}


void Typer::Decorator::Decorate(Node* node) {
  if (node->op()->ValueOutputCount() > 0) {
    // Only eagerly type-decorate nodes with known input types.
    // Other cases will generally require a proper fixpoint iteration with Run.
    bool is_typed = NodeProperties::IsTyped(node);
    if (is_typed || NodeProperties::AllValueInputsAreTyped(node)) {
      Visitor typing(typer_);
      Type* type = typing.TypeNode(node);
      if (is_typed) {
        type = Type::Intersect(type, NodeProperties::GetType(node),
                               typer_->zone());
      }
      NodeProperties::SetType(node, type);
    }
  }
}


// -----------------------------------------------------------------------------

// Helper functions that lift a function f on types to a function on bounds,
// and uses that to type the given node.  Note that f is never called with None
// as an argument.


Type* Typer::Visitor::TypeUnaryOp(Node* node, UnaryTyperFun f) {
  Type* input = Operand(node, 0);
  return input->IsInhabited() ? f(input, typer_) : Type::None();
}


Type* Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) {
  Type* left = Operand(node, 0);
  Type* right = Operand(node, 1);
  return left->IsInhabited() && right->IsInhabited() ? f(left, right, typer_)
                                                     : Type::None();
}


Type* Typer::Visitor::Invert(Type* type, Typer* t) {
  DCHECK(type->Is(Type::Boolean()));
  DCHECK(type->IsInhabited());
  if (type->Is(t->singleton_false_)) return t->singleton_true_;
  if (type->Is(t->singleton_true_)) return t->singleton_false_;
  return type;
}


Typer::Visitor::ComparisonOutcome Typer::Visitor::Invert(
    ComparisonOutcome outcome, Typer* t) {
  ComparisonOutcome result(0);
  if ((outcome & kComparisonUndefined) != 0) result |= kComparisonUndefined;
  if ((outcome & kComparisonTrue) != 0) result |= kComparisonFalse;
  if ((outcome & kComparisonFalse) != 0) result |= kComparisonTrue;
  return result;
}


Type* Typer::Visitor::FalsifyUndefined(ComparisonOutcome outcome, Typer* t) {
  if ((outcome & kComparisonFalse) != 0 ||
      (outcome & kComparisonUndefined) != 0) {
    return (outcome & kComparisonTrue) != 0 ? Type::Boolean()
                                            : t->singleton_false_;
  }
  // Type should be non empty, so we know it should be true.
  DCHECK((outcome & kComparisonTrue) != 0);
  return t->singleton_true_;
}

// Type conversion.

Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) {
  if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) {
    return type;
  }
  return Type::Primitive();
}


Type* Typer::Visitor::ToBoolean(Type* type, Typer* t) {
  if (type->Is(Type::Boolean())) return type;
  if (type->Is(t->falsish_)) return t->singleton_false_;
  if (type->Is(t->truish_)) return t->singleton_true_;
  if (type->Is(Type::PlainNumber()) && (type->Max() < 0 || 0 < type->Min())) {
    return t->singleton_true_;  // Ruled out nan, -0 and +0.
  }
  return Type::Boolean();
}


// static
Type* Typer::Visitor::ToInteger(Type* type, Typer* t) {
  // ES6 section 7.1.4 ToInteger ( argument )
  type = ToNumber(type, t);
  if (type->Is(t->cache_.kIntegerOrMinusZero)) return type;
  if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) {
    return Type::Union(
        Type::Intersect(type, t->cache_.kIntegerOrMinusZero, t->zone()),
        t->cache_.kSingletonZero, t->zone());
  }
  return t->cache_.kIntegerOrMinusZero;
}


// static
Type* Typer::Visitor::ToLength(Type* type, Typer* t) {
  // ES6 section 7.1.15 ToLength ( argument )
  type = ToInteger(type, t);
  double min = type->Min();
  double max = type->Max();
  if (min <= 0.0) min = 0.0;
  if (max > kMaxSafeInteger) max = kMaxSafeInteger;
  if (max <= min) max = min;
  return Type::Range(min, max, t->zone());
}


// static
Type* Typer::Visitor::ToName(Type* type, Typer* t) {
  // ES6 section 7.1.14 ToPropertyKey ( argument )
  type = ToPrimitive(type, t);
  if (type->Is(Type::Name())) return type;
  if (type->Maybe(Type::Symbol())) return Type::Name();
  return ToString(type, t);
}


// static
Type* Typer::Visitor::ToNumber(Type* type, Typer* t) {
  if (type->Is(Type::Number())) return type;
  if (type->Is(Type::NullOrUndefined())) {
    if (type->Is(Type::Null())) return t->cache_.kSingletonZero;
    if (type->Is(Type::Undefined())) return Type::NaN();
    return Type::Union(Type::NaN(), t->cache_.kSingletonZero, t->zone());
  }
  if (type->Is(Type::NumberOrUndefined())) {
    return Type::Union(Type::Intersect(type, Type::Number(), t->zone()),
                       Type::NaN(), t->zone());
  }
  if (type->Is(t->singleton_false_)) return t->cache_.kSingletonZero;
  if (type->Is(t->singleton_true_)) return t->cache_.kSingletonOne;
  if (type->Is(Type::Boolean())) return t->cache_.kZeroOrOne;
  if (type->Is(Type::BooleanOrNumber())) {
    return Type::Union(Type::Intersect(type, Type::Number(), t->zone()),
                       t->cache_.kZeroOrOne, t->zone());
  }
  return Type::Number();
}


// static
Type* Typer::Visitor::ToObject(Type* type, Typer* t) {
  // ES6 section 7.1.13 ToObject ( argument )
  if (type->Is(Type::Receiver())) return type;
  if (type->Is(Type::Primitive())) return Type::OtherObject();
  if (!type->Maybe(Type::OtherUndetectable())) {
    return Type::DetectableReceiver();
  }
  return Type::Receiver();
}


// static
Type* Typer::Visitor::ToString(Type* type, Typer* t) {
  // ES6 section 7.1.12 ToString ( argument )
  type = ToPrimitive(type, t);
  if (type->Is(Type::String())) return type;
  return Type::String();
}

// static
Type* Typer::Visitor::NumberAbs(Type* type, Typer* t) {
  DCHECK(type->Is(Type::Number()));
  Factory* const f = t->isolate()->factory();
  bool const maybe_nan = type->Maybe(Type::NaN());
  bool const maybe_minuszero = type->Maybe(Type::MinusZero());
  type = Type::Intersect(type, Type::PlainNumber(), t->zone());
  double const max = type->Max();
  double const min = type->Min();
  if (min < 0) {
    if (type->Is(t->cache_.kInteger)) {
      type =
          Type::Range(0.0, std::max(std::fabs(min), std::fabs(max)), t->zone());
    } else if (min == max) {
      type = Type::Constant(f->NewNumber(std::fabs(min)), t->zone());
    } else {
      type = Type::PlainNumber();
    }
  }
  if (maybe_minuszero) {
    type = Type::Union(type, t->cache_.kSingletonZero, t->zone());
  }
  if (maybe_nan) {
    type = Type::Union(type, Type::NaN(), t->zone());
  }
  return type;
}

// static
Type* Typer::Visitor::NumberCeil(Type* type, Typer* t) {
  DCHECK(type->Is(Type::Number()));
  if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) return type;
  // TODO(bmeurer): We could infer a more precise type here.
  return t->cache_.kIntegerOrMinusZeroOrNaN;
}

// static
Type* Typer::Visitor::NumberFloor(Type* type, Typer* t) {
  DCHECK(type->Is(Type::Number()));
  if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) return type;
  // TODO(bmeurer): We could infer a more precise type here.
  return t->cache_.kIntegerOrMinusZeroOrNaN;
}

// static
Type* Typer::Visitor::NumberRound(Type* type, Typer* t) {
  DCHECK(type->Is(Type::Number()));
  if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) return type;
  // TODO(bmeurer): We could infer a more precise type here.
  return t->cache_.kIntegerOrMinusZeroOrNaN;
}

// static
Type* Typer::Visitor::NumberTrunc(Type* type, Typer* t) {
  DCHECK(type->Is(Type::Number()));
  if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) return type;
  // TODO(bmeurer): We could infer a more precise type here.
  return t->cache_.kIntegerOrMinusZeroOrNaN;
}

Type* Typer::Visitor::NumberToInt32(Type* type, Typer* t) {
  if (type->Is(Type::Signed32())) return type;
  if (type->Is(t->cache_.kZeroish)) return t->cache_.kSingletonZero;
  if (type->Is(t->signed32ish_)) {
    return Type::Intersect(
        Type::Union(type, t->cache_.kSingletonZero, t->zone()),
        Type::Signed32(), t->zone());
  }
  return Type::Signed32();
}


Type* Typer::Visitor::NumberToUint32(Type* type, Typer* t) {
  if (type->Is(Type::Unsigned32())) return type;
  if (type->Is(t->cache_.kZeroish)) return t->cache_.kSingletonZero;
  if (type->Is(t->unsigned32ish_)) {
    return Type::Intersect(
        Type::Union(type, t->cache_.kSingletonZero, t->zone()),
        Type::Unsigned32(), t->zone());
  }
  return Type::Unsigned32();
}

// Type checks.

Type* Typer::Visitor::ObjectIsCallable(Type* type, Typer* t) {
  if (type->Is(Type::Function())) return t->singleton_true_;
  if (type->Is(Type::Primitive())) return t->singleton_false_;
  return Type::Boolean();
}

Type* Typer::Visitor::ObjectIsNumber(Type* type, Typer* t) {
  if (type->Is(Type::Number())) return t->singleton_true_;
  if (!type->Maybe(Type::Number())) return t->singleton_false_;
  return Type::Boolean();
}


Type* Typer::Visitor::ObjectIsReceiver(Type* type, Typer* t) {
  if (type->Is(Type::Receiver())) return t->singleton_true_;
  if (!type->Maybe(Type::Receiver())) return t->singleton_false_;
  return Type::Boolean();
}


Type* Typer::Visitor::ObjectIsSmi(Type* type, Typer* t) {
  if (type->Is(Type::TaggedSigned())) return t->singleton_true_;
  if (type->Is(Type::TaggedPointer())) return t->singleton_false_;
  return Type::Boolean();
}

Type* Typer::Visitor::ObjectIsString(Type* type, Typer* t) {
  if (type->Is(Type::String())) return t->singleton_true_;
  if (!type->Maybe(Type::String())) return t->singleton_false_;
  return Type::Boolean();
}

Type* Typer::Visitor::ObjectIsUndetectable(Type* type, Typer* t) {
  if (type->Is(Type::Undetectable())) return t->singleton_true_;
  if (!type->Maybe(Type::Undetectable())) return t->singleton_false_;
  return Type::Boolean();
}


// -----------------------------------------------------------------------------


// Control operators.

Type* Typer::Visitor::TypeStart(Node* node) { return Type::Internal(); }

Type* Typer::Visitor::TypeIfException(Node* node) { return Type::Any(); }


// Common operators.


Type* Typer::Visitor::TypeParameter(Node* node) {
  if (FunctionType* function_type = typer_->function_type()) {
    int const index = ParameterIndexOf(node->op());
    if (index >= 0 && index < function_type->Arity()) {
      return function_type->Parameter(index);
    }
  }
  return Type::Any();
}


Type* Typer::Visitor::TypeOsrValue(Node* node) { return Type::Any(); }


Type* Typer::Visitor::TypeInt32Constant(Node* node) {
  double number = OpParameter<int32_t>(node);
  return Type::Intersect(Type::Range(number, number, zone()),
                         Type::UntaggedIntegral32(), zone());
}


Type* Typer::Visitor::TypeInt64Constant(Node* node) {
  // TODO(rossberg): This actually seems to be a PointerConstant so far...
  return Type::Internal();  // TODO(rossberg): Add int64 bitset type?
}

// TODO(gdeepti) : Fix this to do something meaningful.
Type* Typer::Visitor::TypeRelocatableInt32Constant(Node* node) {
  return Type::Internal();
}

Type* Typer::Visitor::TypeRelocatableInt64Constant(Node* node) {
  return Type::Internal();
}

Type* Typer::Visitor::TypeFloat32Constant(Node* node) {
  return Type::Intersect(Type::Of(OpParameter<float>(node), zone()),
                         Type::UntaggedFloat32(), zone());
}


Type* Typer::Visitor::TypeFloat64Constant(Node* node) {
  return Type::Intersect(Type::Of(OpParameter<double>(node), zone()),
                         Type::UntaggedFloat64(), zone());
}


Type* Typer::Visitor::TypeNumberConstant(Node* node) {
  Factory* f = isolate()->factory();
  double number = OpParameter<double>(node);
  if (Type::IsInteger(number)) {
    return Type::Range(number, number, zone());
  }
  return Type::Constant(f->NewNumber(number), zone());
}


Type* Typer::Visitor::TypeHeapConstant(Node* node) {
  return TypeConstant(OpParameter<Handle<HeapObject>>(node));
}


Type* Typer::Visitor::TypeExternalConstant(Node* node) {
  return Type::Internal();
}


Type* Typer::Visitor::TypeSelect(Node* node) {
  return Type::Union(Operand(node, 1), Operand(node, 2), zone());
}


Type* Typer::Visitor::TypePhi(Node* node) {
  int arity = node->op()->ValueInputCount();
  Type* type = Operand(node, 0);
  for (int i = 1; i < arity; ++i) {
    type = Type::Union(type, Operand(node, i), zone());
  }
  return type;
}


Type* Typer::Visitor::TypeEffectPhi(Node* node) {
  UNREACHABLE();
  return nullptr;
}

Type* Typer::Visitor::TypeTypeGuard(Node* node) {
  Type* input_type = Operand(node, 0);
  Type* guard_type = TypeOf(node->op());
  return Type::Intersect(input_type, guard_type, zone());
}

Type* Typer::Visitor::TypeCheckpoint(Node* node) {
  UNREACHABLE();
  return nullptr;
}

Type* Typer::Visitor::TypeBeginRegion(Node* node) {
  UNREACHABLE();
  return nullptr;
}


Type* Typer::Visitor::TypeFinishRegion(Node* node) { return Operand(node, 0); }


Type* Typer::Visitor::TypeFrameState(Node* node) {
  // TODO(rossberg): Ideally FrameState wouldn't have a value output.
  return Type::Internal();
}

Type* Typer::Visitor::TypeStateValues(Node* node) { return Type::Internal(); }

Type* Typer::Visitor::TypeObjectState(Node* node) { return Type::Internal(); }

Type* Typer::Visitor::TypeTypedStateValues(Node* node) {
  return Type::Internal();
}


Type* Typer::Visitor::TypeCall(Node* node) { return Type::Any(); }


Type* Typer::Visitor::TypeProjection(Node* node) {
  Type* const type = Operand(node, 0);
  if (type->Is(Type::None())) return Type::None();
  int const index = static_cast<int>(ProjectionIndexOf(node->op()));
  if (type->IsTuple() && index < type->AsTuple()->Arity()) {
    return type->AsTuple()->Element(index);
  }
  return Type::Any();
}


Type* Typer::Visitor::TypeDead(Node* node) { return Type::Any(); }


// JS comparison operators.


Type* Typer::Visitor::JSEqualTyper(Type* lhs, Type* rhs, Typer* t) {
  if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false_;
  if (lhs->Is(Type::NullOrUndefined()) && rhs->Is(Type::NullOrUndefined())) {
    return t->singleton_true_;
  }
  if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) &&
      (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) {
    return t->singleton_false_;
  }
  if (lhs->IsConstant() && rhs->Is(lhs)) {
    // Types are equal and are inhabited only by a single semantic value,
    // which is not nan due to the earlier check.
    return t->singleton_true_;
  }
  return Type::Boolean();
}


Type* Typer::Visitor::JSNotEqualTyper(Type* lhs, Type* rhs, Typer* t) {
  return Invert(JSEqualTyper(lhs, rhs, t), t);
}


static Type* JSType(Type* type) {
  if (type->Is(Type::Boolean())) return Type::Boolean();
  if (type->Is(Type::String())) return Type::String();
  if (type->Is(Type::Number())) return Type::Number();
  if (type->Is(Type::Undefined())) return Type::Undefined();
  if (type->Is(Type::Null())) return Type::Null();
  if (type->Is(Type::Symbol())) return Type::Symbol();
  if (type->Is(Type::Receiver())) return Type::Receiver();  // JS "Object"
  return Type::Any();
}


Type* Typer::Visitor::JSStrictEqualTyper(Type* lhs, Type* rhs, Typer* t) {
  if (!JSType(lhs)->Maybe(JSType(rhs))) return t->singleton_false_;
  if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false_;
  if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) &&
      (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) {
    return t->singleton_false_;
  }
  if ((lhs->Is(t->singleton_the_hole_) || rhs->Is(t->singleton_the_hole_)) &&
      !lhs->Maybe(rhs)) {
    return t->singleton_false_;
  }
  if (lhs->IsConstant() && rhs->Is(lhs)) {
    // Types are equal and are inhabited only by a single semantic value,
    // which is not nan due to the earlier check.
    return t->singleton_true_;
  }
  return Type::Boolean();
}


Type* Typer::Visitor::JSStrictNotEqualTyper(Type* lhs, Type* rhs, Typer* t) {
  return Invert(JSStrictEqualTyper(lhs, rhs, t), t);
}


// The EcmaScript specification defines the four relational comparison operators
// (<, <=, >=, >) with the help of a single abstract one.  It behaves like <
// but returns undefined when the inputs cannot be compared.
// We implement the typing analogously.
Typer::Visitor::ComparisonOutcome Typer::Visitor::JSCompareTyper(Type* lhs,
                                                                 Type* rhs,
                                                                 Typer* t) {
  lhs = ToPrimitive(lhs, t);
  rhs = ToPrimitive(rhs, t);
  if (lhs->Maybe(Type::String()) && rhs->Maybe(Type::String())) {
    return ComparisonOutcome(kComparisonTrue) |
           ComparisonOutcome(kComparisonFalse);
  }
  lhs = ToNumber(lhs, t);
  rhs = ToNumber(rhs, t);

  // Shortcut for NaNs.
  if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return kComparisonUndefined;

  ComparisonOutcome result;
  if (lhs->IsConstant() && rhs->Is(lhs)) {
    // Types are equal and are inhabited only by a single semantic value.
    result = kComparisonFalse;
  } else if (lhs->Min() >= rhs->Max()) {
    result = kComparisonFalse;
  } else if (lhs->Max() < rhs->Min()) {
    result = kComparisonTrue;
  } else {
    // We cannot figure out the result, return both true and false. (We do not
    // have to return undefined because that cannot affect the result of
    // FalsifyUndefined.)
    return ComparisonOutcome(kComparisonTrue) |
           ComparisonOutcome(kComparisonFalse);
  }
  // Add the undefined if we could see NaN.
  if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) {
    result |= kComparisonUndefined;
  }
  return result;
}


Type* Typer::Visitor::JSLessThanTyper(Type* lhs, Type* rhs, Typer* t) {
  return FalsifyUndefined(JSCompareTyper(lhs, rhs, t), t);
}


Type* Typer::Visitor::JSGreaterThanTyper(Type* lhs, Type* rhs, Typer* t) {
  return FalsifyUndefined(JSCompareTyper(rhs, lhs, t), t);
}


Type* Typer::Visitor::JSLessThanOrEqualTyper(Type* lhs, Type* rhs, Typer* t) {
  return FalsifyUndefined(Invert(JSCompareTyper(rhs, lhs, t), t), t);
}


Type* Typer::Visitor::JSGreaterThanOrEqualTyper(
    Type* lhs, Type* rhs, Typer* t) {
  return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t);
}

// JS bitwise operators.


Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) {
  lhs = NumberToInt32(ToNumber(lhs, t), t);
  rhs = NumberToInt32(ToNumber(rhs, t), t);
  double lmin = lhs->Min();
  double rmin = rhs->Min();
  double lmax = lhs->Max();
  double rmax = rhs->Max();
  // Or-ing any two values results in a value no smaller than their minimum.
  // Even no smaller than their maximum if both values are non-negative.
  double min =
      lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin);
  double max = Type::Signed32()->Max();

  // Or-ing with 0 is essentially a conversion to int32.
  if (rmin == 0 && rmax == 0) {
    min = lmin;
    max = lmax;
  }
  if (lmin == 0 && lmax == 0) {
    min = rmin;
    max = rmax;
  }

  if (lmax < 0 || rmax < 0) {
    // Or-ing two values of which at least one is negative results in a negative
    // value.
    max = std::min(max, -1.0);
  }
  return Type::Range(min, max, t->zone());
}


Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) {
  lhs = NumberToInt32(ToNumber(lhs, t), t);
  rhs = NumberToInt32(ToNumber(rhs, t), t);
  double lmin = lhs->Min();
  double rmin = rhs->Min();
  double lmax = lhs->Max();
  double rmax = rhs->Max();
  double min = Type::Signed32()->Min();
  // And-ing any two values results in a value no larger than their maximum.
  // Even no larger than their minimum if both values are non-negative.
  double max =
      lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax);
  // And-ing with a non-negative value x causes the result to be between
  // zero and x.
  if (lmin >= 0) {
    min = 0;
    max = std::min(max, lmax);
  }
  if (rmin >= 0) {
    min = 0;
    max = std::min(max, rmax);
  }
  return Type::Range(min, max, t->zone());
}


Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) {
  lhs = NumberToInt32(ToNumber(lhs, t), t);
  rhs = NumberToInt32(ToNumber(rhs, t), t);
  double lmin = lhs->Min();
  double rmin = rhs->Min();
  double lmax = lhs->Max();
  double rmax = rhs->Max();
  if ((lmin >= 0 && rmin >= 0) || (lmax < 0 && rmax < 0)) {
    // Xor-ing negative or non-negative values results in a non-negative value.
    return Type::Unsigned31();
  }
  if ((lmax < 0 && rmin >= 0) || (lmin >= 0 && rmax < 0)) {
    // Xor-ing a negative and a non-negative value results in a negative value.
    // TODO(jarin) Use a range here.
    return Type::Negative32();
  }
  return Type::Signed32();
}


Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) {
  return Type::Signed32();
}


Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) {
  lhs = NumberToInt32(ToNumber(lhs, t), t);
  rhs = NumberToUint32(ToNumber(rhs, t), t);
  double min = kMinInt;
  double max = kMaxInt;
  if (lhs->Min() >= 0) {
    // Right-shifting a non-negative value cannot make it negative, nor larger.
    min = std::max(min, 0.0);
    max = std::min(max, lhs->Max());
    if (rhs->Min() > 0 && rhs->Max() <= 31) {
      max = static_cast<int>(max) >> static_cast<int>(rhs->Min());
    }
  }
  if (lhs->Max() < 0) {
    // Right-shifting a negative value cannot make it non-negative, nor smaller.
    min = std::max(min, lhs->Min());
    max = std::min(max, -1.0);
    if (rhs->Min() > 0 && rhs->Max() <= 31) {
      min = static_cast<int>(min) >> static_cast<int>(rhs->Min());
    }
  }
  if (rhs->Min() > 0 && rhs->Max() <= 31) {
    // Right-shifting by a positive value yields a small integer value.
    double shift_min = kMinInt >> static_cast<int>(rhs->Min());
    double shift_max = kMaxInt >> static_cast<int>(rhs->Min());
    min = std::max(min, shift_min);
    max = std::min(max, shift_max);
  }
  // TODO(jarin) Ideally, the following micro-optimization should be performed
  // by the type constructor.
  if (max != Type::Signed32()->Max() || min != Type::Signed32()->Min()) {
    return Type::Range(min, max, t->zone());
  }
  return Type::Signed32();
}


Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) {
  lhs = NumberToUint32(ToNumber(lhs, t), t);
  // Logical right-shifting any value cannot make it larger.
  return Type::Range(0.0, lhs->Max(), t->zone());
}


// JS arithmetic operators.

Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) {
  lhs = ToPrimitive(lhs, t);
  rhs = ToPrimitive(rhs, t);
  if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) {
    if (lhs->Is(Type::String()) || rhs->Is(Type::String())) {
      return Type::String();
    } else {
      return Type::NumberOrString();
    }
  }
  // The addition must be numeric.
  return t->operation_typer()->NumericAdd(ToNumber(lhs, t), ToNumber(rhs, t));
}

Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) {
  return t->operation_typer()->NumericSubtract(ToNumber(lhs, t),
                                               ToNumber(rhs, t));
}

Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) {
  return t->operation_typer()->NumericMultiply(ToNumber(lhs, t),
                                               ToNumber(rhs, t));
}

Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) {
  return t->operation_typer()->NumericDivide(ToNumber(lhs, t),
                                             ToNumber(rhs, t));
  lhs = ToNumber(lhs, t);
  rhs = ToNumber(rhs, t);
  if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
  // Division is tricky, so all we do is try ruling out nan.
  bool maybe_nan =
      lhs->Maybe(Type::NaN()) || rhs->Maybe(t->cache_.kZeroish) ||
      ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) &&
       (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY));
  return maybe_nan ? Type::Number() : Type::OrderedNumber();
}

Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
  return t->operation_typer()->NumericModulus(ToNumber(lhs, t),
                                              ToNumber(rhs, t));
}


// JS unary operators.


Type* Typer::Visitor::JSTypeOfTyper(Type* type, Typer* t) {
  Factory* const f = t->isolate()->factory();
  if (type->Is(Type::Boolean())) {
    return Type::Constant(f->boolean_string(), t->zone());
  } else if (type->Is(Type::Number())) {
    return Type::Constant(f->number_string(), t->zone());
  } else if (type->Is(Type::String())) {
    return Type::Constant(f->string_string(), t->zone());
  } else if (type->Is(Type::Symbol())) {
    return Type::Constant(f->symbol_string(), t->zone());
  } else if (type->Is(Type::Union(Type::Undefined(), Type::OtherUndetectable(),
                                  t->zone()))) {
    return Type::Constant(f->undefined_string(), t->zone());
  } else if (type->Is(Type::Null())) {
    return Type::Constant(f->object_string(), t->zone());
  } else if (type->Is(Type::Function())) {
    return Type::Constant(f->function_string(), t->zone());
  } else if (type->IsConstant()) {
    return Type::Constant(
        Object::TypeOf(t->isolate(), type->AsConstant()->Value()), t->zone());
  }
  return Type::InternalizedString();
}


Type* Typer::Visitor::TypeJSTypeOf(Node* node) {
  return TypeUnaryOp(node, JSTypeOfTyper);
}


// JS conversion operators.


Type* Typer::Visitor::TypeJSToBoolean(Node* node) {
  return TypeUnaryOp(node, ToBoolean);
}

Type* Typer::Visitor::TypeJSToInteger(Node* node) {
  return TypeUnaryOp(node, ToInteger);
}

Type* Typer::Visitor::TypeJSToLength(Node* node) {
  return TypeUnaryOp(node, ToLength);
}

Type* Typer::Visitor::TypeJSToName(Node* node) {
  return TypeUnaryOp(node, ToName);
}

Type* Typer::Visitor::TypeJSToNumber(Node* node) {
  return TypeUnaryOp(node, ToNumber);
}

Type* Typer::Visitor::TypeJSToObject(Node* node) {
  return TypeUnaryOp(node, ToObject);
}

Type* Typer::Visitor::TypeJSToString(Node* node) {
  return TypeUnaryOp(node, ToString);
}

// JS object operators.


Type* Typer::Visitor::TypeJSCreate(Node* node) { return Type::Object(); }


Type* Typer::Visitor::TypeJSCreateArguments(Node* node) {
  return Type::OtherObject();
}


Type* Typer::Visitor::TypeJSCreateArray(Node* node) {
  return Type::OtherObject();
}


Type* Typer::Visitor::TypeJSCreateClosure(Node* node) {
  return Type::Function();
}


Type* Typer::Visitor::TypeJSCreateIterResultObject(Node* node) {
  return Type::OtherObject();
}


Type* Typer::Visitor::TypeJSCreateLiteralArray(Node* node) {
  return Type::OtherObject();
}


Type* Typer::Visitor::TypeJSCreateLiteralObject(Node* node) {
  return Type::OtherObject();
}


Type* Typer::Visitor::TypeJSCreateLiteralRegExp(Node* node) {
  return Type::OtherObject();
}


Type* Typer::Visitor::JSLoadPropertyTyper(Type* object, Type* name, Typer* t) {
  // TODO(rossberg): Use range types and sized array types to filter undefined.
  if (object->IsArray() && name->Is(Type::Integral32())) {
    return Type::Union(
        object->AsArray()->Element(), Type::Undefined(), t->zone());
  }
  return Type::Any();
}


Type* Typer::Visitor::TypeJSLoadProperty(Node* node) {
  return TypeBinaryOp(node, JSLoadPropertyTyper);
}


Type* Typer::Visitor::TypeJSLoadNamed(Node* node) {
  return Type::Any();
}


Type* Typer::Visitor::TypeJSLoadGlobal(Node* node) { return Type::Any(); }


// Returns a somewhat larger range if we previously assigned
// a (smaller) range to this node. This is used  to speed up
// the fixpoint calculation in case there appears to be a loop
// in the graph. In the current implementation, we are
// increasing the limits to the closest power of two.
Type* Typer::Visitor::Weaken(Node* node, Type* current_type,
                             Type* previous_type) {
  static const double kWeakenMinLimits[] = {
      0.0, -1073741824.0, -2147483648.0, -4294967296.0, -8589934592.0,
      -17179869184.0, -34359738368.0, -68719476736.0, -137438953472.0,
      -274877906944.0, -549755813888.0, -1099511627776.0, -2199023255552.0,
      -4398046511104.0, -8796093022208.0, -17592186044416.0, -35184372088832.0,
      -70368744177664.0, -140737488355328.0, -281474976710656.0,
      -562949953421312.0};
  static const double kWeakenMaxLimits[] = {
      0.0, 1073741823.0, 2147483647.0, 4294967295.0, 8589934591.0,
      17179869183.0, 34359738367.0, 68719476735.0, 137438953471.0,
      274877906943.0, 549755813887.0, 1099511627775.0, 2199023255551.0,
      4398046511103.0, 8796093022207.0, 17592186044415.0, 35184372088831.0,
      70368744177663.0, 140737488355327.0, 281474976710655.0,
      562949953421311.0};
  STATIC_ASSERT(arraysize(kWeakenMinLimits) == arraysize(kWeakenMaxLimits));

  // If the types have nothing to do with integers, return the types.
  Type* const integer = typer_->cache_.kInteger;
  if (!previous_type->Maybe(integer)) {
    return current_type;
  }
  DCHECK(current_type->Maybe(integer));

  Type* current_integer = Type::Intersect(current_type, integer, zone());
  Type* previous_integer = Type::Intersect(previous_type, integer, zone());

  // Once we start weakening a node, we should always weaken.
  if (!IsWeakened(node->id())) {
    // Only weaken if there is range involved; we should converge quickly
    // for all other types (the exception is a union of many constants,
    // but we currently do not increase the number of constants in unions).
    Type* previous = previous_integer->GetRange();
    Type* current = current_integer->GetRange();
    if (current == nullptr || previous == nullptr) {
      return current_type;
    }
    // Range is involved => we are weakening.
    SetWeakened(node->id());
  }

  double current_min = current_integer->Min();
  double new_min = current_min;
  // Find the closest lower entry in the list of allowed
  // minima (or negative infinity if there is no such entry).
  if (current_min != previous_integer->Min()) {
    new_min = -V8_INFINITY;
    for (double const min : kWeakenMinLimits) {
      if (min <= current_min) {
        new_min = min;
        break;
      }
    }
  }

  double current_max = current_integer->Max();
  double new_max = current_max;
  // Find the closest greater entry in the list of allowed
  // maxima (or infinity if there is no such entry).
  if (current_max != previous_integer->Max()) {
    new_max = V8_INFINITY;
    for (double const max : kWeakenMaxLimits) {
      if (max >= current_max) {
        new_max = max;
        break;
      }
    }
  }

  return Type::Union(current_type,
                     Type::Range(new_min, new_max, typer_->zone()),
                     typer_->zone());
}


Type* Typer::Visitor::TypeJSStoreProperty(Node* node) {
  UNREACHABLE();
  return nullptr;
}


Type* Typer::Visitor::TypeJSStoreNamed(Node* node) {
  UNREACHABLE();
  return nullptr;
}


Type* Typer::Visitor::TypeJSStoreGlobal(Node* node) {
  UNREACHABLE();
  return nullptr;
}


Type* Typer::Visitor::TypeJSDeleteProperty(Node* node) {
  return Type::Boolean();
}

Type* Typer::Visitor::TypeJSHasProperty(Node* node) { return Type::Boolean(); }

Type* Typer::Visitor::TypeJSInstanceOf(Node* node) { return Type::Boolean(); }

// JS context operators.


Type* Typer::Visitor::TypeJSLoadContext(Node* node) {
  ContextAccess const& access = ContextAccessOf(node->op());
  if (access.index() == Context::EXTENSION_INDEX) {
    return Type::TaggedPointer();
  }
  // Since contexts are mutable, we just return the top.
  return Type::Any();
}


Type* Typer::Visitor::TypeJSStoreContext(Node* node) {
  UNREACHABLE();
  return nullptr;
}


Type* Typer::Visitor::WrapContextTypeForInput(Node* node) {
  Type* outer = TypeOrNone(NodeProperties::GetContextInput(node));
  if (outer->Is(Type::None())) {
    return Type::None();
  } else {
    DCHECK(outer->Maybe(Type::Internal()));
    return Type::Context(outer, zone());
  }
}


Type* Typer::Visitor::TypeJSCreateFunctionContext(Node* node) {
  return WrapContextTypeForInput(node);
}


Type* Typer::Visitor::TypeJSCreateCatchContext(Node* node) {
  return WrapContextTypeForInput(node);
}


Type* Typer::Visitor::TypeJSCreateWithContext(Node* node) {
  return WrapContextTypeForInput(node);
}


Type* Typer::Visitor::TypeJSCreateBlockContext(Node* node) {
  return WrapContextTypeForInput(node);
}


Type* Typer::Visitor::TypeJSCreateModuleContext(Node* node) {
  // TODO(rossberg): this is probably incorrect
  return WrapContextTypeForInput(node);
}


Type* Typer::Visitor::TypeJSCreateScriptContext(Node* node) {
  return WrapContextTypeForInput(node);
}


// JS other operators.


Type* Typer::Visitor::TypeJSCallConstruct(Node* node) {
  return Type::Receiver();
}


Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) {
  if (fun->IsFunction()) {
    return fun->AsFunction()->Result();
  }
  if (fun->IsConstant() && fun->AsConstant()->Value()->IsJSFunction()) {
    Handle<JSFunction> function =
        Handle<JSFunction>::cast(fun->AsConstant()->Value());
    if (function->shared()->HasBuiltinFunctionId()) {
      switch (function->shared()->builtin_function_id()) {
        case kMathRandom:
          return Type::OrderedNumber();
        case kMathFloor:
        case kMathCeil:
        case kMathRound:
        case kMathTrunc:
          return t->cache_.kIntegerOrMinusZeroOrNaN;
        // Unary math functions.
        case kMathExp:
          return Type::Union(Type::PlainNumber(), Type::NaN(), t->zone());
        case kMathAbs:
        case kMathLog:
        case kMathSqrt:
        case kMathCos:
        case kMathSin:
        case kMathTan:
        case kMathAcos:
        case kMathAsin:
        case kMathAtan:
        case kMathFround:
          return Type::Number();
        // Binary math functions.
        case kMathAtan2:
        case kMathPow:
        case kMathMax:
        case kMathMin:
          return Type::Number();
        case kMathImul:
          return Type::Signed32();
        case kMathClz32:
          return t->cache_.kZeroToThirtyTwo;
        // String functions.
        case kStringCharCodeAt:
          return Type::Union(Type::Range(0, kMaxUInt16, t->zone()), Type::NaN(),
                             t->zone());
        case kStringCharAt:
        case kStringConcat:
        case kStringFromCharCode:
        case kStringToLowerCase:
        case kStringToUpperCase:
          return Type::String();
        // Array functions.
        case kArrayIndexOf:
        case kArrayLastIndexOf:
          return Type::Number();
        default:
          break;
      }
    }
  }
  return Type::Any();
}


Type* Typer::Visitor::TypeJSCallFunction(Node* node) {
  // TODO(bmeurer): We could infer better types if we wouldn't ignore the
  // argument types for the JSCallFunctionTyper above.
  return TypeUnaryOp(node, JSCallFunctionTyper);
}


Type* Typer::Visitor::TypeJSCallRuntime(Node* node) {
  switch (CallRuntimeParametersOf(node->op()).id()) {
    case Runtime::kInlineIsJSReceiver:
      return TypeUnaryOp(node, ObjectIsReceiver);
    case Runtime::kInlineIsSmi:
      return TypeUnaryOp(node, ObjectIsSmi);
    case Runtime::kInlineIsArray:
    case Runtime::kInlineIsDate:
    case Runtime::kInlineIsTypedArray:
    case Runtime::kInlineIsRegExp:
      return Type::Boolean();
    case Runtime::kInlineDoubleLo:
    case Runtime::kInlineDoubleHi:
      return Type::Signed32();
    case Runtime::kInlineCreateIterResultObject:
    case Runtime::kInlineRegExpConstructResult:
      return Type::OtherObject();
    case Runtime::kInlineSubString:
    case Runtime::kInlineStringCharFromCode:
      return Type::String();
    case Runtime::kInlineToInteger:
      return TypeUnaryOp(node, ToInteger);
    case Runtime::kInlineToLength:
      return TypeUnaryOp(node, ToLength);
    case Runtime::kInlineToName:
      return TypeUnaryOp(node, ToName);
    case Runtime::kInlineToNumber:
      return TypeUnaryOp(node, ToNumber);
    case Runtime::kInlineToObject:
      return TypeUnaryOp(node, ToObject);
    case Runtime::kInlineToPrimitive:
    case Runtime::kInlineToPrimitive_Number:
    case Runtime::kInlineToPrimitive_String:
      return TypeUnaryOp(node, ToPrimitive);
    case Runtime::kInlineToString:
      return TypeUnaryOp(node, ToString);
    case Runtime::kHasInPrototypeChain:
      return Type::Boolean();
    default:
      break;
  }
  return Type::Any();
}


Type* Typer::Visitor::TypeJSConvertReceiver(Node* node) {
  return Type::Receiver();
}


Type* Typer::Visitor::TypeJSForInNext(Node* node) {
  return Type::Union(Type::Name(), Type::Undefined(), zone());
}


Type* Typer::Visitor::TypeJSForInPrepare(Node* node) {
  STATIC_ASSERT(Map::EnumLengthBits::kMax <= FixedArray::kMaxLength);
  Factory* const f = isolate()->factory();
  Type* const cache_type = Type::Union(
      typer_->cache_.kSmi, Type::Class(f->meta_map(), zone()), zone());
  Type* const cache_array = Type::Class(f->fixed_array_map(), zone());
  Type* const cache_length = typer_->cache_.kFixedArrayLengthType;
  return Type::Tuple(cache_type, cache_array, cache_length, zone());
}

Type* Typer::Visitor::TypeJSForInDone(Node* node) { return Type::Boolean(); }

Type* Typer::Visitor::TypeJSForInStep(Node* node) {
  STATIC_ASSERT(Map::EnumLengthBits::kMax <= FixedArray::kMaxLength);
  return Type::Range(1, FixedArray::kMaxLength + 1, zone());
}


Type* Typer::Visitor::TypeJSLoadMessage(Node* node) { return Type::Any(); }


Type* Typer::Visitor::TypeJSStoreMessage(Node* node) {
  UNREACHABLE();
  return nullptr;
}

Type* Typer::Visitor::TypeJSGeneratorStore(Node* node) {
  UNREACHABLE();
  return nullptr;
}

Type* Typer::Visitor::TypeJSGeneratorRestoreContinuation(Node* node) {
  return typer_->cache_.kSmi;
}

Type* Typer::Visitor::TypeJSGeneratorRestoreRegister(Node* node) {
  return Type::Any();
}

Type* Typer::Visitor::TypeJSStackCheck(Node* node) { return Type::Any(); }

// Simplified operators.

Type* Typer::Visitor::TypeBooleanNot(Node* node) { return Type::Boolean(); }

Type* Typer::Visitor::TypeBooleanToNumber(Node* node) {
  return TypeUnaryOp(node, ToNumber);
}

Type* Typer::Visitor::TypeNumberEqual(Node* node) { return Type::Boolean(); }

Type* Typer::Visitor::TypeNumberLessThan(Node* node) { return Type::Boolean(); }

Type* Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) {
  return Type::Boolean();
}

Type* Typer::Visitor::TypeSpeculativeNumberEqual(Node* node) {
  return Type::Boolean();
}

Type* Typer::Visitor::TypeSpeculativeNumberLessThan(Node* node) {
  return Type::Boolean();
}

Type* Typer::Visitor::TypeSpeculativeNumberLessThanOrEqual(Node* node) {
  return Type::Boolean();
}

Type* Typer::Visitor::TypeNumberAdd(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeNumberSubtract(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeSpeculativeNumberAdd(Node* node) {
  return Type::Number();
}

Type* Typer::Visitor::TypeSpeculativeNumberSubtract(Node* node) {
  return Type::Number();
}

Type* Typer::Visitor::TypeSpeculativeNumberMultiply(Node* node) {
  return Type::Number();
}

Type* Typer::Visitor::TypeSpeculativeNumberDivide(Node* node) {
  return Type::Number();
}

Type* Typer::Visitor::TypeSpeculativeNumberModulus(Node* node) {
  return Type::Number();
}

Type* Typer::Visitor::TypeNumberMultiply(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeNumberDivide(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeNumberModulus(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeNumberBitwiseOr(Node* node) {
  return Type::Signed32();
}


Type* Typer::Visitor::TypeNumberBitwiseXor(Node* node) {
  return Type::Signed32();
}


Type* Typer::Visitor::TypeNumberBitwiseAnd(Node* node) {
  return Type::Signed32();
}


Type* Typer::Visitor::TypeNumberShiftLeft(Node* node) {
  return Type::Signed32();
}


Type* Typer::Visitor::TypeNumberShiftRight(Node* node) {
  return Type::Signed32();
}


Type* Typer::Visitor::TypeNumberShiftRightLogical(Node* node) {
  return Type::Unsigned32();
}

Type* Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) {
  return TypeUnaryOp(node, ToNumber);
}

Type* Typer::Visitor::TypePlainPrimitiveToWord32(Node* node) {
  return Type::Integral32();
}

Type* Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) {
  return Type::Number();
}

Type* Typer::Visitor::TypeNumberImul(Node* node) { return Type::Signed32(); }

Type* Typer::Visitor::TypeNumberAbs(Node* node) {
  return TypeUnaryOp(node, NumberAbs);
}

Type* Typer::Visitor::TypeNumberClz32(Node* node) {
  return typer_->cache_.kZeroToThirtyTwo;
}

Type* Typer::Visitor::TypeNumberCeil(Node* node) {
  return TypeUnaryOp(node, NumberCeil);
}

Type* Typer::Visitor::TypeNumberFloor(Node* node) {
  return TypeUnaryOp(node, NumberFloor);
}

Type* Typer::Visitor::TypeNumberFround(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeNumberAtan(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeNumberAtan2(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeNumberAtanh(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeNumberCos(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeNumberExp(Node* node) {
  return Type::Union(Type::PlainNumber(), Type::NaN(), zone());
}

// TODO(mvstanton): Is this type sufficient, or should it look like Exp()?
Type* Typer::Visitor::TypeNumberExpm1(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeNumberLog(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeNumberLog1p(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeNumberLog2(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeNumberLog10(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeNumberCbrt(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeNumberRound(Node* node) {
  return TypeUnaryOp(node, NumberRound);
}

Type* Typer::Visitor::TypeNumberSin(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeNumberSqrt(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeNumberTan(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeNumberTrunc(Node* node) {
  return TypeUnaryOp(node, NumberTrunc);
}

Type* Typer::Visitor::TypeNumberToInt32(Node* node) {
  return TypeUnaryOp(node, NumberToInt32);
}


Type* Typer::Visitor::TypeNumberToUint32(Node* node) {
  return TypeUnaryOp(node, NumberToUint32);
}


// static
Type* Typer::Visitor::ReferenceEqualTyper(Type* lhs, Type* rhs, Typer* t) {
  if (lhs->IsConstant() && rhs->Is(lhs)) {
    return t->singleton_true_;
  }
  return Type::Boolean();
}


Type* Typer::Visitor::TypeReferenceEqual(Node* node) {
  return TypeBinaryOp(node, ReferenceEqualTyper);
}

Type* Typer::Visitor::TypeStringEqual(Node* node) { return Type::Boolean(); }

Type* Typer::Visitor::TypeStringLessThan(Node* node) { return Type::Boolean(); }

Type* Typer::Visitor::TypeStringLessThanOrEqual(Node* node) {
  return Type::Boolean();
}

Type* Typer::Visitor::StringFromCharCodeTyper(Type* type, Typer* t) {
  type = NumberToUint32(ToNumber(type, t), t);
  Factory* f = t->isolate()->factory();
  double min = type->Min();
  double max = type->Max();
  if (min == max) {
    uint32_t code = static_cast<uint32_t>(min) & String::kMaxUtf16CodeUnitU;
    Handle<String> string = f->LookupSingleCharacterStringFromCode(code);
    return Type::Constant(string, t->zone());
  }
  return Type::String();
}

Type* Typer::Visitor::TypeStringFromCharCode(Node* node) {
  return TypeUnaryOp(node, StringFromCharCodeTyper);
}

Type* Typer::Visitor::TypeStringToNumber(Node* node) {
  return TypeUnaryOp(node, ToNumber);
}

namespace {

Type* ChangeRepresentation(Type* type, Type* rep, Zone* zone) {
  return Type::Union(Type::Semantic(type, zone),
                     Type::Representation(rep, zone), zone);
}

}  // namespace

Type* Typer::Visitor::TypeChangeTaggedSignedToInt32(Node* node) {
  Type* arg = Operand(node, 0);
  // TODO(jarin): DCHECK(arg->Is(Type::Signed32()));
  // Many tests fail this check.
  return ChangeRepresentation(arg, Type::UntaggedIntegral32(), zone());
}

Type* Typer::Visitor::TypeChangeTaggedToInt32(Node* node) {
  Type* arg = Operand(node, 0);
  DCHECK(arg->Is(Type::Signed32()));
  return ChangeRepresentation(arg, Type::UntaggedIntegral32(), zone());
}


Type* Typer::Visitor::TypeChangeTaggedToUint32(Node* node) {
  Type* arg = Operand(node, 0);
  DCHECK(arg->Is(Type::Unsigned32()));
  return ChangeRepresentation(arg, Type::UntaggedIntegral32(), zone());
}


Type* Typer::Visitor::TypeChangeTaggedToFloat64(Node* node) {
  Type* arg = Operand(node, 0);
  DCHECK(arg->Is(Type::Number()));
  return ChangeRepresentation(arg, Type::UntaggedFloat64(), zone());
}

Type* Typer::Visitor::TypeTruncateTaggedToFloat64(Node* node) {
  Type* arg = Operand(node, 0);
  // TODO(jarin) This DCHECK does not work because of speculative feedback.
  // Re-enable once we record the speculative feedback in types.
  // DCHECK(arg->Is(Type::NumberOrOddball()));
  return ChangeRepresentation(arg, Type::UntaggedFloat64(), zone());
}

Type* Typer::Visitor::TypeChangeInt31ToTaggedSigned(Node* node) {
  Type* arg = Operand(node, 0);
  // TODO(jarin): DCHECK(arg->Is(Type::Signed31()));
  // Some mjsunit/asm and mjsunit/wasm tests fail this check.
  // For instance, asm/int32-umod fails with Signed32/UntaggedIntegral32 in
  // simplified-lowering (after propagation).
  Type* rep =
      arg->Is(Type::SignedSmall()) ? Type::TaggedSigned() : Type::Tagged();
  return ChangeRepresentation(arg, rep, zone());
}

Type* Typer::Visitor::TypeChangeInt32ToTagged(Node* node) {
  Type* arg = Operand(node, 0);
  // TODO(jarin): DCHECK(arg->Is(Type::Signed32()));
  // Two tests fail this check: mjsunit/asm/sqlite3/sqlite-safe-heap and
  // mjsunit/wasm/embenchen/lua_binarytrees. The first one fails with Any/Any in
  // simplified-lowering (after propagation).
  Type* rep =
      arg->Is(Type::SignedSmall()) ? Type::TaggedSigned() : Type::Tagged();
  return ChangeRepresentation(arg, rep, zone());
}

Type* Typer::Visitor::TypeChangeUint32ToTagged(Node* node) {
  Type* arg = Operand(node, 0);
  // TODO(jarin): DCHECK(arg->Is(Type::Unsigned32()));
  // This fails in benchmarks/octane/mandreel (--turbo).
  return ChangeRepresentation(arg, Type::Tagged(), zone());
}

Type* Typer::Visitor::TypeChangeFloat64ToTagged(Node* node) {
  Type* arg = Operand(node, 0);
  // TODO(jarin): DCHECK(arg->Is(Type::Number()));
  // Some (or all) mjsunit/wasm/embenchen/ tests fail this check when run with
  // --turbo and --always-opt.
  return ChangeRepresentation(arg, Type::Tagged(), zone());
}

Type* Typer::Visitor::TypeChangeTaggedToBit(Node* node) {
  Type* arg = Operand(node, 0);
  DCHECK(arg->Is(Type::Boolean()));
  return ChangeRepresentation(arg, Type::UntaggedBit(), zone());
}

Type* Typer::Visitor::TypeChangeBitToTagged(Node* node) {
  Type* arg = Operand(node, 0);
  return ChangeRepresentation(arg, Type::TaggedPointer(), zone());
}

Type* Typer::Visitor::TypeCheckBounds(Node* node) {
  // TODO(bmeurer): We could do better here based on the limit.
  return Type::Unsigned31();
}

Type* Typer::Visitor::TypeCheckTaggedPointer(Node* node) {
  Type* arg = Operand(node, 0);
  return Type::Intersect(arg, Type::TaggedPointer(), zone());
}

Type* Typer::Visitor::TypeCheckTaggedSigned(Node* node) {
  Type* arg = Operand(node, 0);
  return Type::Intersect(arg, typer_->cache_.kSmi, zone());
}

Type* Typer::Visitor::TypeCheckedInt32Add(Node* node) {
  return Type::Integral32();
}

Type* Typer::Visitor::TypeCheckedInt32Sub(Node* node) {
  return Type::Integral32();
}

Type* Typer::Visitor::TypeCheckedUint32ToInt32(Node* node) {
  return Type::Signed32();
}

Type* Typer::Visitor::TypeCheckedFloat64ToInt32(Node* node) {
  return Type::Signed32();
}

Type* Typer::Visitor::TypeCheckedTaggedToInt32(Node* node) {
  return Type::Signed32();
}

Type* Typer::Visitor::TypeCheckedTaggedToFloat64(Node* node) {
  return Type::Number();
}

Type* Typer::Visitor::TypeCheckFloat64Hole(Node* node) {
  Type* type = Operand(node, 0);
  return type;
}

Type* Typer::Visitor::TypeCheckTaggedHole(Node* node) {
  CheckTaggedHoleMode mode = CheckTaggedHoleModeOf(node->op());
  Type* type = Operand(node, 0);
  type = Type::Intersect(type, Type::NonInternal(), zone());
  switch (mode) {
    case CheckTaggedHoleMode::kConvertHoleToUndefined: {
      // The hole is turned into undefined.
      type = Type::Union(type, Type::Undefined(), zone());
      break;
    }
    case CheckTaggedHoleMode::kNeverReturnHole: {
      // We deoptimize in case of the hole.
      break;
    }
  }
  return type;
}

Type* Typer::Visitor::TypeTruncateTaggedToWord32(Node* node) {
  Type* arg = Operand(node, 0);
  // TODO(jarin): DCHECK(arg->Is(Type::NumberOrUndefined()));
  // Several mjsunit and cctest tests fail this check. For instance,
  // mjsunit/compiler/regress-607493 fails with Any/Any in simplified-lowering
  // (after propagation).
  return ChangeRepresentation(arg, Type::UntaggedIntegral32(), zone());
}

Type* Typer::Visitor::TypeAllocate(Node* node) { return Type::TaggedPointer(); }


namespace {

MaybeHandle<Map> GetStableMapFromObjectType(Type* object_type) {
  if (object_type->IsConstant() &&
      object_type->AsConstant()->Value()->IsHeapObject()) {
    Handle<Map> object_map(
        Handle<HeapObject>::cast(object_type->AsConstant()->Value())->map());
    if (object_map->is_stable()) return object_map;
  } else if (object_type->IsClass()) {
    Handle<Map> object_map = object_type->AsClass()->Map();
    if (object_map->is_stable()) return object_map;
  }
  return MaybeHandle<Map>();
}

}  // namespace


Type* Typer::Visitor::TypeLoadField(Node* node) {
  FieldAccess const& access = FieldAccessOf(node->op());
  if (access.base_is_tagged == kTaggedBase &&
      access.offset == HeapObject::kMapOffset) {
    // The type of LoadField[Map](o) is Constant(map) if map is stable and
    // either
    //  (a) o has type Constant(object) and map == object->map, or
    //  (b) o has type Class(map),
    // and either
    //  (1) map cannot transition further, or
    //  (2) deoptimization is enabled and we can add a code dependency on the
    //      stability of map (to guard the Constant type information).
    Type* const object = Operand(node, 0);
    if (object->Is(Type::None())) return Type::None();
    Handle<Map> object_map;
    if (GetStableMapFromObjectType(object).ToHandle(&object_map)) {
      if (object_map->CanTransition()) {
        if (flags() & kDeoptimizationEnabled) {
          dependencies()->AssumeMapStable(object_map);
        } else {
          return access.type;
        }
      }
      Type* object_map_type = Type::Constant(object_map, zone());
      DCHECK(object_map_type->Is(access.type));
      return object_map_type;
    }
  }
  return access.type;
}


Type* Typer::Visitor::TypeLoadBuffer(Node* node) {
  // TODO(bmeurer): This typing is not yet correct. Since we can still access
  // out of bounds, the type in the general case has to include Undefined.
  switch (BufferAccessOf(node->op()).external_array_type()) {
#define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype, size) \
  case kExternal##ElemType##Array:                          \
    return Type::Union(typer_->cache_.k##ElemType, Type::Undefined(), zone());
    TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE
  }
  UNREACHABLE();
  return nullptr;
}


Type* Typer::Visitor::TypeLoadElement(Node* node) {
  return ElementAccessOf(node->op()).type;
}


Type* Typer::Visitor::TypeStoreField(Node* node) {
  UNREACHABLE();
  return nullptr;
}


Type* Typer::Visitor::TypeStoreBuffer(Node* node) {
  UNREACHABLE();
  return nullptr;
}


Type* Typer::Visitor::TypeStoreElement(Node* node) {
  UNREACHABLE();
  return nullptr;
}

Type* Typer::Visitor::TypeObjectIsCallable(Node* node) {
  return TypeUnaryOp(node, ObjectIsCallable);
}

Type* Typer::Visitor::TypeObjectIsNumber(Node* node) {
  return TypeUnaryOp(node, ObjectIsNumber);
}


Type* Typer::Visitor::TypeObjectIsReceiver(Node* node) {
  return TypeUnaryOp(node, ObjectIsReceiver);
}


Type* Typer::Visitor::TypeObjectIsSmi(Node* node) {
  return TypeUnaryOp(node, ObjectIsSmi);
}

Type* Typer::Visitor::TypeObjectIsString(Node* node) {
  return TypeUnaryOp(node, ObjectIsString);
}

Type* Typer::Visitor::TypeObjectIsUndetectable(Node* node) {
  return TypeUnaryOp(node, ObjectIsUndetectable);
}


// Machine operators.

Type* Typer::Visitor::TypeDebugBreak(Node* node) { return Type::None(); }

Type* Typer::Visitor::TypeComment(Node* node) { return Type::None(); }

Type* Typer::Visitor::TypeLoad(Node* node) { return Type::Any(); }

Type* Typer::Visitor::TypeStackSlot(Node* node) { return Type::Any(); }

Type* Typer::Visitor::TypeStore(Node* node) {
  UNREACHABLE();
  return nullptr;
}


Type* Typer::Visitor::TypeWord32And(Node* node) { return Type::Integral32(); }


Type* Typer::Visitor::TypeWord32Or(Node* node) { return Type::Integral32(); }


Type* Typer::Visitor::TypeWord32Xor(Node* node) { return Type::Integral32(); }


Type* Typer::Visitor::TypeWord32Shl(Node* node) { return Type::Integral32(); }


Type* Typer::Visitor::TypeWord32Shr(Node* node) { return Type::Integral32(); }


Type* Typer::Visitor::TypeWord32Sar(Node* node) { return Type::Integral32(); }


Type* Typer::Visitor::TypeWord32Ror(Node* node) { return Type::Integral32(); }


Type* Typer::Visitor::TypeWord32Equal(Node* node) { return Type::Boolean(); }


Type* Typer::Visitor::TypeWord32Clz(Node* node) { return Type::Integral32(); }


Type* Typer::Visitor::TypeWord32Ctz(Node* node) { return Type::Integral32(); }


Type* Typer::Visitor::TypeWord32ReverseBits(Node* node) {
  return Type::Integral32();
}


Type* Typer::Visitor::TypeWord32Popcnt(Node* node) {
  return Type::Integral32();
}


Type* Typer::Visitor::TypeWord64And(Node* node) { return Type::Internal(); }


Type* Typer::Visitor::TypeWord64Or(Node* node) { return Type::Internal(); }


Type* Typer::Visitor::TypeWord64Xor(Node* node) { return Type::Internal(); }


Type* Typer::Visitor::TypeWord64Shl(Node* node) { return Type::Internal(); }


Type* Typer::Visitor::TypeWord64Shr(Node* node) { return Type::Internal(); }


Type* Typer::Visitor::TypeWord64Sar(Node* node) { return Type::Internal(); }


Type* Typer::Visitor::TypeWord64Ror(Node* node) { return Type::Internal(); }


Type* Typer::Visitor::TypeWord64Clz(Node* node) { return Type::Internal(); }


Type* Typer::Visitor::TypeWord64Ctz(Node* node) { return Type::Internal(); }


Type* Typer::Visitor::TypeWord64ReverseBits(Node* node) {
  return Type::Internal();
}


Type* Typer::Visitor::TypeWord64Popcnt(Node* node) { return Type::Internal(); }


Type* Typer::Visitor::TypeWord64Equal(Node* node) { return Type::Boolean(); }


Type* Typer::Visitor::TypeInt32Add(Node* node) { return Type::Integral32(); }


Type* Typer::Visitor::TypeInt32AddWithOverflow(Node* node) {
  return Type::Internal();
}


Type* Typer::Visitor::TypeInt32Sub(Node* node) { return Type::Integral32(); }


Type* Typer::Visitor::TypeInt32SubWithOverflow(Node* node) {
  return Type::Internal();
}


Type* Typer::Visitor::TypeInt32Mul(Node* node) { return Type::Integral32(); }


Type* Typer::Visitor::TypeInt32MulHigh(Node* node) { return Type::Signed32(); }


Type* Typer::Visitor::TypeInt32Div(Node* node) { return Type::Integral32(); }


Type* Typer::Visitor::TypeInt32Mod(Node* node) { return Type::Integral32(); }


Type* Typer::Visitor::TypeInt32LessThan(Node* node) { return Type::Boolean(); }


Type* Typer::Visitor::TypeInt32LessThanOrEqual(Node* node) {
  return Type::Boolean();
}


Type* Typer::Visitor::TypeUint32Div(Node* node) { return Type::Unsigned32(); }


Type* Typer::Visitor::TypeUint32LessThan(Node* node) { return Type::Boolean(); }


Type* Typer::Visitor::TypeUint32LessThanOrEqual(Node* node) {
  return Type::Boolean();
}


Type* Typer::Visitor::TypeUint32Mod(Node* node) { return Type::Unsigned32(); }


Type* Typer::Visitor::TypeUint32MulHigh(Node* node) {
  return Type::Unsigned32();
}


Type* Typer::Visitor::TypeInt64Add(Node* node) { return Type::Internal(); }


Type* Typer::Visitor::TypeInt64AddWithOverflow(Node* node) {
  return Type::Internal();
}


Type* Typer::Visitor::TypeInt64Sub(Node* node) { return Type::Internal(); }


Type* Typer::Visitor::TypeInt64SubWithOverflow(Node* node) {
  return Type::Internal();
}


Type* Typer::Visitor::TypeInt64Mul(Node* node) { return Type::Internal(); }


Type* Typer::Visitor::TypeInt64Div(Node* node) { return Type::Internal(); }


Type* Typer::Visitor::TypeInt64Mod(Node* node) { return Type::Internal(); }


Type* Typer::Visitor::TypeInt64LessThan(Node* node) { return Type::Boolean(); }


Type* Typer::Visitor::TypeInt64LessThanOrEqual(Node* node) {
  return Type::Boolean();
}


Type* Typer::Visitor::TypeUint64Div(Node* node) { return Type::Internal(); }


Type* Typer::Visitor::TypeUint64LessThan(Node* node) { return Type::Boolean(); }


Type* Typer::Visitor::TypeUint64LessThanOrEqual(Node* node) {
  return Type::Boolean();
}


Type* Typer::Visitor::TypeUint64Mod(Node* node) { return Type::Internal(); }

Type* Typer::Visitor::TypeBitcastWordToTagged(Node* node) {
  return Type::TaggedPointer();
}

Type* Typer::Visitor::TypeChangeFloat32ToFloat64(Node* node) {
  return Type::Intersect(Type::Number(), Type::UntaggedFloat64(), zone());
}


Type* Typer::Visitor::TypeChangeFloat64ToInt32(Node* node) {
  return Type::Intersect(Type::Signed32(), Type::UntaggedIntegral32(), zone());
}

Type* Typer::Visitor::TypeNumberSilenceNaN(Node* node) {
  return Type::Number();
}

Type* Typer::Visitor::TypeChangeFloat64ToUint32(Node* node) {
  return Type::Intersect(Type::Unsigned32(), Type::UntaggedIntegral32(),
                         zone());
}

Type* Typer::Visitor::TypeTruncateFloat64ToUint32(Node* node) {
  return Type::Intersect(Type::Unsigned32(), Type::UntaggedIntegral32(),
                         zone());
}

Type* Typer::Visitor::TypeTruncateFloat32ToInt32(Node* node) {
  return Type::Intersect(Type::Signed32(), Type::UntaggedIntegral32(), zone());
}


Type* Typer::Visitor::TypeTruncateFloat32ToUint32(Node* node) {
  return Type::Intersect(Type::Unsigned32(), Type::UntaggedIntegral32(),
                         zone());
}


Type* Typer::Visitor::TypeTryTruncateFloat32ToInt64(Node* node) {
  return Type::Internal();
}


Type* Typer::Visitor::TypeTryTruncateFloat64ToInt64(Node* node) {
  return Type::Internal();
}


Type* Typer::Visitor::TypeTryTruncateFloat32ToUint64(Node* node) {
  return Type::Internal();
}


Type* Typer::Visitor::TypeTryTruncateFloat64ToUint64(Node* node) {
  return Type::Internal();
}


Type* Typer::Visitor::TypeChangeInt32ToFloat64(Node* node) {
  return Type::Intersect(Type::Signed32(), Type::UntaggedFloat64(), zone());
}

Type* Typer::Visitor::TypeFloat64SilenceNaN(Node* node) {
  return Type::UntaggedFloat64();
}

Type* Typer::Visitor::TypeChangeInt32ToInt64(Node* node) {
  return Type::Internal();
}


Type* Typer::Visitor::TypeChangeUint32ToFloat64(Node* node) {
  return Type::Intersect(Type::Unsigned32(), Type::UntaggedFloat64(), zone());
}


Type* Typer::Visitor::TypeChangeUint32ToUint64(Node* node) {
  return Type::Internal();
}


Type* Typer::Visitor::TypeTruncateFloat64ToFloat32(Node* node) {
  return Type::Intersect(Type::Number(), Type::UntaggedFloat32(), zone());
}

Type* Typer::Visitor::TypeTruncateFloat64ToWord32(Node* node) {
  return Type::Intersect(Type::Integral32(), Type::UntaggedIntegral32(),
                         zone());
}


Type* Typer::Visitor::TypeTruncateInt64ToInt32(Node* node) {
  return Type::Intersect(Type::Signed32(), Type::UntaggedIntegral32(), zone());
}

Type* Typer::Visitor::TypeRoundFloat64ToInt32(Node* node) {
  return Type::Intersect(Type::Signed32(), Type::UntaggedIntegral32(), zone());
}

Type* Typer::Visitor::TypeRoundInt32ToFloat32(Node* node) {
  return Type::Intersect(Type::PlainNumber(), Type::UntaggedFloat32(), zone());
}


Type* Typer::Visitor::TypeRoundInt64ToFloat32(Node* node) {
  return Type::Intersect(Type::PlainNumber(), Type::UntaggedFloat32(), zone());
}


Type* Typer::Visitor::TypeRoundInt64ToFloat64(Node* node) {
  return Type::Intersect(Type::PlainNumber(), Type::UntaggedFloat64(), zone());
}


Type* Typer::Visitor::TypeRoundUint32ToFloat32(Node* node) {
  return Type::Intersect(Type::PlainNumber(), Type::UntaggedFloat32(), zone());
}


Type* Typer::Visitor::TypeRoundUint64ToFloat32(Node* node) {
  return Type::Intersect(Type::PlainNumber(), Type::UntaggedFloat32(), zone());
}


Type* Typer::Visitor::TypeRoundUint64ToFloat64(Node* node) {
  return Type::Intersect(Type::PlainNumber(), Type::UntaggedFloat64(), zone());
}


Type* Typer::Visitor::TypeBitcastFloat32ToInt32(Node* node) {
  return Type::Number();
}


Type* Typer::Visitor::TypeBitcastFloat64ToInt64(Node* node) {
  return Type::Number();
}


Type* Typer::Visitor::TypeBitcastInt32ToFloat32(Node* node) {
  return Type::Number();
}


Type* Typer::Visitor::TypeBitcastInt64ToFloat64(Node* node) {
  return Type::Number();
}


Type* Typer::Visitor::TypeFloat32Add(Node* node) { return Type::Number(); }


Type* Typer::Visitor::TypeFloat32Sub(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeFloat32SubPreserveNan(Node* node) {
  return Type::Number();
}

Type* Typer::Visitor::TypeFloat32Neg(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeFloat32Mul(Node* node) { return Type::Number(); }


Type* Typer::Visitor::TypeFloat32Div(Node* node) { return Type::Number(); }


Type* Typer::Visitor::TypeFloat32Max(Node* node) { return Type::Number(); }


Type* Typer::Visitor::TypeFloat32Min(Node* node) { return Type::Number(); }


Type* Typer::Visitor::TypeFloat32Abs(Node* node) {
  // TODO(turbofan): We should be able to infer a better type here.
  return Type::Number();
}


Type* Typer::Visitor::TypeFloat32Sqrt(Node* node) { return Type::Number(); }


Type* Typer::Visitor::TypeFloat32Equal(Node* node) { return Type::Boolean(); }


Type* Typer::Visitor::TypeFloat32LessThan(Node* node) {
  return Type::Boolean();
}


Type* Typer::Visitor::TypeFloat32LessThanOrEqual(Node* node) {
  return Type::Boolean();
}


Type* Typer::Visitor::TypeFloat64Add(Node* node) { return Type::Number(); }


Type* Typer::Visitor::TypeFloat64Sub(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeFloat64SubPreserveNan(Node* node) {
  return Type::Number();
}

Type* Typer::Visitor::TypeFloat64Neg(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeFloat64Mul(Node* node) { return Type::Number(); }


Type* Typer::Visitor::TypeFloat64Div(Node* node) { return Type::Number(); }


Type* Typer::Visitor::TypeFloat64Mod(Node* node) { return Type::Number(); }


Type* Typer::Visitor::TypeFloat64Max(Node* node) { return Type::Number(); }


Type* Typer::Visitor::TypeFloat64Min(Node* node) { return Type::Number(); }


Type* Typer::Visitor::TypeFloat64Abs(Node* node) {
  // TODO(turbofan): We should be able to infer a better type here.
  return Type::Number();
}

Type* Typer::Visitor::TypeFloat64Atan(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeFloat64Atan2(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeFloat64Atanh(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeFloat64Cos(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeFloat64Exp(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeFloat64Expm1(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeFloat64Log(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeFloat64Log1p(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeFloat64Log2(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeFloat64Log10(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeFloat64Cbrt(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeFloat64Sin(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeFloat64Sqrt(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeFloat64Tan(Node* node) { return Type::Number(); }

Type* Typer::Visitor::TypeFloat64Equal(Node* node) { return Type::Boolean(); }


Type* Typer::Visitor::TypeFloat64LessThan(Node* node) {
  return Type::Boolean();
}


Type* Typer::Visitor::TypeFloat64LessThanOrEqual(Node* node) {
  return Type::Boolean();
}


Type* Typer::Visitor::TypeFloat32RoundDown(Node* node) {
  // TODO(sigurds): We could have a tighter bound here.
  return Type::Number();
}


Type* Typer::Visitor::TypeFloat64RoundDown(Node* node) {
  // TODO(sigurds): We could have a tighter bound here.
  return Type::Number();
}


Type* Typer::Visitor::TypeFloat32RoundUp(Node* node) {
  // TODO(sigurds): We could have a tighter bound here.
  return Type::Number();
}


Type* Typer::Visitor::TypeFloat64RoundUp(Node* node) {
  // TODO(sigurds): We could have a tighter bound here.
  return Type::Number();
}


Type* Typer::Visitor::TypeFloat32RoundTruncate(Node* node) {
  // TODO(sigurds): We could have a tighter bound here.
  return Type::Number();
}


Type* Typer::Visitor::TypeFloat64RoundTruncate(Node* node) {
  // TODO(sigurds): We could have a tighter bound here.
  return Type::Number();
}


Type* Typer::Visitor::TypeFloat64RoundTiesAway(Node* node) {
  // TODO(sigurds): We could have a tighter bound here.
  return Type::Number();
}


Type* Typer::Visitor::TypeFloat32RoundTiesEven(Node* node) {
  // TODO(sigurds): We could have a tighter bound here.
  return Type::Number();
}


Type* Typer::Visitor::TypeFloat64RoundTiesEven(Node* node) {
  // TODO(sigurds): We could have a tighter bound here.
  return Type::Number();
}


Type* Typer::Visitor::TypeFloat64ExtractLowWord32(Node* node) {
  return Type::Signed32();
}


Type* Typer::Visitor::TypeFloat64ExtractHighWord32(Node* node) {
  return Type::Signed32();
}


Type* Typer::Visitor::TypeFloat64InsertLowWord32(Node* node) {
  return Type::Number();
}


Type* Typer::Visitor::TypeFloat64InsertHighWord32(Node* node) {
  return Type::Number();
}


Type* Typer::Visitor::TypeLoadStackPointer(Node* node) {
  return Type::Internal();
}


Type* Typer::Visitor::TypeLoadFramePointer(Node* node) {
  return Type::Internal();
}

Type* Typer::Visitor::TypeLoadParentFramePointer(Node* node) {
  return Type::Internal();
}

Type* Typer::Visitor::TypeCheckedLoad(Node* node) { return Type::Any(); }

Type* Typer::Visitor::TypeCheckedStore(Node* node) {
  UNREACHABLE();
  return nullptr;
}

Type* Typer::Visitor::TypeAtomicLoad(Node* node) { return Type::Any(); }

Type* Typer::Visitor::TypeAtomicStore(Node* node) {
  UNREACHABLE();
  return nullptr;
}

Type* Typer::Visitor::TypeInt32PairAdd(Node* node) { return Type::Internal(); }

Type* Typer::Visitor::TypeInt32PairSub(Node* node) { return Type::Internal(); }

Type* Typer::Visitor::TypeInt32PairMul(Node* node) { return Type::Internal(); }

Type* Typer::Visitor::TypeWord32PairShl(Node* node) { return Type::Internal(); }

Type* Typer::Visitor::TypeWord32PairShr(Node* node) { return Type::Internal(); }

Type* Typer::Visitor::TypeWord32PairSar(Node* node) { return Type::Internal(); }

// SIMD type methods.

#define SIMD_RETURN_SIMD(Name) \
  Type* Typer::Visitor::Type##Name(Node* node) { return Type::Simd(); }
MACHINE_SIMD_RETURN_SIMD_OP_LIST(SIMD_RETURN_SIMD)
MACHINE_SIMD_GENERIC_OP_LIST(SIMD_RETURN_SIMD)
#undef SIMD_RETURN_SIMD

#define SIMD_RETURN_NUM(Name) \
  Type* Typer::Visitor::Type##Name(Node* node) { return Type::Number(); }
MACHINE_SIMD_RETURN_NUM_OP_LIST(SIMD_RETURN_NUM)
#undef SIMD_RETURN_NUM

#define SIMD_RETURN_BOOL(Name) \
  Type* Typer::Visitor::Type##Name(Node* node) { return Type::Boolean(); }
MACHINE_SIMD_RETURN_BOOL_OP_LIST(SIMD_RETURN_BOOL)
#undef SIMD_RETURN_BOOL

// Heap constants.

Type* Typer::Visitor::TypeConstant(Handle<Object> value) {
  if (value->IsJSTypedArray()) {
    switch (JSTypedArray::cast(*value)->type()) {
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
  case kExternal##Type##Array:                          \
    return typer_->cache_.k##Type##Array;
      TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE
    }
  }
  if (Type::IsInteger(*value)) {
    return Type::Range(value->Number(), value->Number(), zone());
  }
  return Type::Constant(value, zone());
}

}  // namespace compiler
}  // namespace internal
}  // namespace v8
